我应该向继承db.Model的类添加方法,还是应该将这些类继承到新类?

时间:2011-06-30 12:53:28

标签: python google-app-engine google-cloud-datastore models

使用继承db.Model的类时,更好的做法是添加方法,还是应该创建一个单独的类?

例如,如果我想在帖子上存储信息,我应该有Post扩展db.Model,还是应该有PostData扩展db.Model和Post扩展(甚至引用?)PostData?

我认为,差异在于,继承db.Model的类不会创建没有所有必需属性的实例。我希望看到的行为不是保存到没有必需属性的数据存储区。哪个更干净?哪个更受欢迎?

3 个答案:

答案 0 :(得分:2)

提示:使用与数据存储模型分离的业务逻辑

我认为你应该以最纯粹的形式使用你的模型。

您可以让其他处理程序将其用作显式类型。 不继承它们是一些更清洁。想想数据连接。您可以在断开连接或处于连接状态下使用模型。

在ruby中,我会在模型上使用mixins或concern_with模式

在python中我建议使用Django,因此您的视图可能包含大部分业务逻辑。 http://www.djangobook.com/en/1.0/chapter05/

尝试使用mixins!

  

mixin类是一种使用类的继承功能从较小的行为组成一个类的方法。

https://docs.djangoproject.com/en/dev/ref/class-based-views/

答案 1 :(得分:2)

db.Model子类添加方法是非常好的做法。如果你想要由几个模型类共享的通用功能,那么让你的实际模型子类本身就是一个db.Model子类只有任何意义 - 就像在标准继承中一样。

我不确定您提出的方法如何帮助“不保存到没有必需属性的数据存储区”,除非您计划创建自己的数据模型,转换为数据存储模型和从数据存储模型转换 - 这只是浪费时间(无论是你的还是处理器)。数据存储库的工作方式,不可能创建具有不验证值的模型,我不确定您为什么要这样做。

答案 2 :(得分:0)

另一种方法是使用合成(通常是继承的更好替代方法)。 e.g。

class MyModel(db.Model): pass

# Avoiding inheritance.
class MyWrapper(object):

  def __init__(self, my_model):
    # The leading _ indicates that methods in this class should
    # access self._my_model.
    self._my_model = my_model

许多人会认为这是不必要的间接,我不会责怪那些人。但是,如果您希望以MyModel中的validator参数不支持的方式约束db.Property个实例,那么这可能会很好。 E.g。

class MyModel(db.Model):
  # f(x, y, z) = 0
  x = db.FloatProperty()
  y = db.FloatProperty()
  z = db.FloatProperty()

在没有MyWrapper帮助的情况下执行约束会更难。

使用包装器的另一个原因是您希望实现自己的缓存方案,尽管ndb以更一般的方式解决了这个问题。当MyModel只能通过MyWrapper进行操作时,您可以控制哪些突变是可能的。然后,您可以根据需要注意使缓存条目无效。