让我们假设我使用Mongoengine来创建像这样的文档:
class Tag(Document):
name = fields.StringField(required=True, unique=True)
user = fields.ReferenceField('User')
created = fields.DateTimeField()
updated = fields.DateTimeField(default=datetime.datetime.now)
created
和updated
是在其他模型中经常使用的字段,我希望将与日期时间相关的内容的代码分隔为" mixin"。使用多重继承是一种解决方案:
class Tag(Timestampable, Document):
name = fields.StringField(required=True, unique=True)
user = fields.ReferenceField('User')
class Timestampable()
created = fields.DateTimeField()
updated = fields.DateTimeField(default=datetime.datetime.now)
虽然这有效,multiple inheritance in Python has its serious downsides。因此,我们需要另一种解决我想到了类装饰器:
@Timestampable
class Tag(Document):
name = fields.StringField(required=True, unique=True)
user = fields.ReferenceField('User')
def Timestampable(cls)
cls.created = fields.DateTimeField()
cls.updated = fields.DateTimeField(default=datetime.datetime.now)
return cls
很酷,因为我不需要打扰任何super
来电。
虽然不起作用。引用DateTimeField
类时,不会创建Tag
。
我的问题有解决办法吗?
为了正确理解对此的需求,这里是Timestampable装饰器的完整mixin代码:
def Timestampable(cls):
cls.created = model_fields.DateTimeField()
cls.updated = model_fields.DateTimeField(default=datetime.datetime.now)
cls_save = cls.save
def save(self, *args, **kwargs):
now = datetime.datetime.now()
if not self.id:
self.created = now
self.updated = now
return cls_save(self, *args, **kwargs)
cls.save = save
return cls