【问题标题】:Automatic creation date for Django model form objects?Django模型表单对象的自动创建日期?
【发布时间】: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__ 方法?

【问题讨论】:

    标签: python django django-models


    【解决方案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()
    • 我认为@gregoltsov 的评论此时已过时。使用 auto_now_addauto_now 效果很好。它在保存模型之前设置字段 (github.com/django/django/blob/stable/3.0.x/django/db/models/…)。
    • 谢谢@yndolok 和蒲公英 - 我已经删除了我的评论,所以它不会混淆登陆这个答案的人!
    【解决方案2】:

    好吧,上面的答案是正确的,auto_now_addauto_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”的类。
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 2012-09-27
    • 2018-02-05
    • 1970-01-01
    • 2022-10-14
    • 2016-12-09
    相关资源
    最近更新 更多