Django模型表单对象的自动创建日期?

Posted

技术标签:

【中文标题】Django模型表单对象的自动创建日期?【英文标题】:Automatic creation date for Django model form objects? 【发布时间】:2011-03-26 16:26:26 【问题描述】:

自动设置对象的创建日期以及记录对象上次更新时间的字段的最佳方法是什么?

models.py:

created_at = models.DateTimeField(False, True, editable=False)
updated_at = models.DateTimeField(True, True, editable=False)

views.py:

if request.method == 'POST':
    form = MyForm(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        return HttpResponseRedirect('obj_list')

我得到错误:

objects_object.created_at may not be NULL

我必须自己手动设置这个值吗?我认为这是传递给DateTimeField 的参数的重点(或者它们只是默认值,因为我设置了editable=False,它们不会显示在表单上,​​因此不会在请求中提交,因此不要进入表格?)。

这样做的最佳方法是什么? __init__ 方法?

【问题讨论】:

【参考方案1】:

您可以分别为updated_atcreated_at 使用auto_nowauto_now_add 选项。

class MyModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

【讨论】:

它会产生这个错误:You are trying to add a non-nullable field 'created_at' to gameuser 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) 2) Quit, and let me add a default in models.py Select an option: 1 Please enter the default value now, as valid Python The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now() >>> timezone.now() 删除数据库中的行,或者勾选选项1并添加timezone.now() Django REST Framework seems to think this is a fine approach. 我认为@gregoltsov 的评论此时已过时。使用 auto_now_addauto_now 效果很好。它在保存模型之前设置字段 (github.com/django/django/blob/stable/3.0.x/django/db/models/…)。 谢谢@yndolok 和蒲公英 - 我已经删除了我的评论,所以它不会混淆登陆这个答案的人!【参考方案2】:

好吧,上面的答案是正确的,auto_now_add 和 auto_now 会这样做,但最好创建一个抽象类并在需要 created_atupdated_at 字段的任何模型中使用它。

class TimeStampMixin(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

现在,您可以在任何想要使用它的地方进行简单的继承,并且可以在您喜欢的任何模型中使用时间戳

class Posts(TimeStampMixin):
    name = models.CharField(max_length=50)
    ...
    ...

通过这种方式,您可以在 Django DRY 中利用面向对象的可重用性(不要重复自己)

【讨论】:

很快你就会发现自己有 7 层继承,不明白到底发生了什么……或者更好的是,7 层继承合并为一个名为“Utility”的类。

以上是关于Django模型表单对象的自动创建日期?的主要内容,如果未能解决你的问题,请参考以下文章

Django模型对象过滤关于日期范围以查找创建对象的初始日期?

如何在 Django 中从 2 个不同的模型对象创建表单对象?

Django 从一个表单创建多个对象(相同模型)

Django框架:模型 定义属性

Python自动化运维之28Django

如何将 Django 模型字段的默认值设置为函数调用/可调用(例如,相对于模型对象创建时间的日期)