ChatGPT解决这个技术问题 Extra ChatGPT

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

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

模型.py:

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

视图.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__ 方法?


p
phoenix

您可以分别对 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 和蒲公英 - 我已经删除了我的评论,所以它不会混淆登陆这个答案的人!
C
Chitrank Dixit

好吧,上面的答案是正确的,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”的类。
@Spidey 我对您的评论感到矛盾:一方面,我非常同意抽象滥用(尤其是 OOP 风格的)往往不是一件坏事。然而,在这种情况下,在我看来,它就像一个“好的(因为它是可预测的并且通常有用的)模式/实践封装”的案例,当你考虑它时,它就是 Django 等框架的本质。
@cjauvin 我理解你的立场,我自己也去过那里,但老实说,我认为这个例子属于 composition over inheritance。从库/框架中汲取灵感是可以的,但请记住,项目代码不需要是可重用的。但它需要快速修改,并且在这方面添加继承层可能会造成伤害。
S
Samir Jemaa

如果不提供默认值,就不可能将带有“auto_now_add=True”的字段“create_at”添加到本地。这是因为数据库需要一些东西来填充现有的行