如何强制 Django 模型中的 2 个字段共享相同的默认值



我有一个Django模型MyModel如下所示。

它有两个类型为日期时间字段的字段:my_field1my_field2

from django.db import models
from datetime import datetime
class MyModel(models.Model):
    my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
    my_field2 = models.DateTimeField(
        # WHAT DO I PUT HERE?
    ) 

我希望两个字段都默认为 datetime.utcnow() 的值。但我想为两者保存相同的值。给utcnow()两次打电话似乎很浪费。

如何设置默认值 my_field2,以便它简单地复制默认值 my_field1

正确的

方法是覆盖 save 方法而不是 __init__ 方法。事实上,不建议覆盖 init 方法,更好的方法是覆盖from_db如果您希望控制对象的读取方式,或者如果要控制它们的保存方式,则保存方法。

class MyModel(models.Model):
    my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
    my_field2 = models.DateTimeField()
    def save(self, *arges, **kwargs):
        if self.my_field1 is None:
            self.my_field1 = datetime.utcnow()
            if self.my_field2 is None:
                self.my_field2 = self.my_field1
        super(MyModel, self).save(*args, **kwargs)

更新:我的索赔参考:https://docs.djangoproject.com/en/1.9/ref/models/instances/

您可能想通过覆盖 init 来自定义模型 方法。但是,如果您这样做,请注意不要更改调用 签名,因为任何更改都可能阻止模型实例 保存。与其覆盖 init,不如尝试使用以下之一 方法:

如文档中所述:

创建新模型实例且未为字段提供值时使用默认值。

因此,为了解决您的任务,我将在__init__中手动填充默认值。像这样:

def __init__(self, *args, **kwargs):
    now = datetime.datetime.utcnow()
    kwargs.setdefault('my_field1', now)
    kwargs.setdefault('my_field2', now)
    super(MyModel, self).__init__(*args, **kwargs)

或者,您可以在save方法中处理这些值。

如果您希望my_field2具有my_field1中的任何值,我会使用此解决方案:

class MyModel(models.Model):
    my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
    my_field2 = models.DateTimeField()
    def __init__(self, **kwargs):
        super(MyModel, self).__init__(**kwargs)
        if self.my_field2 is None:
            self.my_field2 = self.my_field1

最新更新