我是一个Django/python新手。我添加了两个字段,以便企业和Django管理员的更改记录为谁更新了它们以及更新日期。
约束是这些字段不能为空。
我的修改如下:
class Enterprise(models.Model):
last_updated = models.DateTimeField(
null=False,
auto_now=True,
verbose_name='Last Updated Date',
help_text="Points to time this was last modified",
)
last_updated_by = models.CharField(
null=False,
max_length=100,
default='N/A',
)
与
class EnterpriseAdmin(admin.ModelAdmin):
model = Enterprise
readonly_fields = (
"last_updated",
"last_updated_by",)
fieldsets = ('last_updated','last_updated_by',),
但是当我运行pytest时,我收到一个错误:* 列“last_updated”中的空值违反了非空约束 *。
当我运行makemigrations时,Django提示我为last_updated添加一个默认值:You are trying to add a non-nullable field 'last_updated' to enterprise without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows)
所以我选择了选项'1',default=datetime.datetime(1970, 1, 1, 0, 0),preserve_default=False,
被添加到我的迁移文件中的last_updated。
migrations.AddField(
model_name='enterprise',
name='last_updated',
field=models.DateTimeField(auto_now=True, default=datetime.datetime(1970, 1, 1, 0, 0), help_text='Points to time this was last modified', verbose_name='Last Updated Date'),
preserve_default=False,
),
我的印象是Unix epoch将作为默认值添加到所有现有列中。
2条答案
按热度按时间fdbelqdn1#
我的印象是Unix epoch将作为默认值添加到所有现有列中。
我在django-4.2上测试了这个,它确实如此,当然可能是这样的,对于一些(非常)旧的版本来说,情况并非如此。
然后,您需要自己提供一个默认值,幸运的是,您可以使用
timezone.now
实际上,您可以使用以下命令指定当前日期时间:
这将在迁移运行时将该字段设置为时间戳。话虽如此,这可能很奇怪,因为这不是记录最后一次被修改的时间,所以也许
null=True
是一个更合理的决定。e4yzc0pl2#
当添加一个新的字段到一个已有表的模型中时,Django需要一个值来用于所有已经存在的行。
如果该字段指定了一个
default
,那么每个人都很高兴,因为这很好,很简单。如果字段是可空的并且没有默认值,Django会将现有行的列设置为空。这显然不适用于非空字段。
如果没有这两种解决方案,Django会问你它应该做什么。它不会悄悄地在任何字段上设置非空值,因为这可能会产生意外的影响。
也许你已经有一个命令,检查企业,foos和酒吧,每天晚上运行。它使用
getattr
来确定对象是否具有last_updated
属性,并删除20年前或更久以前最后更新的所有条目。在这种情况下,将默认值设置为1970可能会无意中删除数据库的很大一部分。