Django Model中auto_now字段在update时不生效的原因与解决方案
本文解析Django中auto_now和auto_now_add字段在调用update方法时不自动更新的原因。由于update直接生成SQL跳过Model层,导致时间字段未被修改。提供了两种解决方案:使用save方法或手动指定datetime.now()进行赋值,确保数据一致性。
Django中auto_now字段的定义与行为
在Django模型定义中,通常使用gmt_create字段配合auto_now_add参数来自动记录创建时间,而使用gmt_modify字段配合auto_now参数来自动记录最后修改时间。
class CommonInfo(models.Model):
"""基类,提供共同信息,不会创建真实的table"""
class Meta:
# 声明自己为抽象基类
abstract = True
# 下面表示先根据更新时间gmt_modify降序排序,如果更新时间相同,再根据创建时间gmt_create降序排序
ordering = ['-gmt_modify', '-gmt_create']
gmt_create = models.DateTimeField('创建时间,自动创建', auto_now_add=True, null=True, help_text='创建时间')
# 使用save可以达到自动更新的效果,使用update不会自动更新,因此需要携带上这个字段
gmt_modify = models.DateTimeField('更新时间,自动更新', auto_now=True, null=True, help_text='更新时间')
Django的ORM提供了两种主要的数据库更新方式:update方法和save方法。
当使用save方法时,系统会自动处理auto_now字段的更新。
save方法与update方法的机制差异
obj = User.objects.get(id=1)
obj.name='xxx'
obj.save()
调用save()方法确实能够自动更新当前的时间字段。
这是因为save操作完整经过了Django的Model层,触发了预定义的信号和字段逻辑。
然而,使用update方法时,auto_now字段不会自动更新。因此,在使用filter结合update进行批量更新时,必须手动将时间字段赋值为datetime.datetime.now()。
如果使用Django filter的update方法(通常用于批量更新数据),其原理是直接调用底层SQL语句,而不经过Model层的处理逻辑。
示例代码如下:User.objects.filter(id=1).update(username='xxx')
补充说明:Django中设置auto_now=True时,时间字段并不会总是自动更新。
auto_now=True生效的前提条件是操作必须通过Django的Model层进行。
例如使用create或save方法时,会自动触发时间更新。
如果先使用filter筛选,再调用update方法,则直接执行SQL语句,不经过Model层。
因此,auto_now字段的时间不会被自动更新。官方对此的解释如下:
What you consider a bug, others may consider a feature, e.g. usingupdate_fieldsto bypass updating fields withauto_now. In fact, I wouldn't expectauto_nowfields to be updated if not present inupdate_fields.
针对上述问题的解决办法主要有两种。
要么强制改用save()方法,要么在调用update时手动传入时间参数。
具体实现方式如下所示。
update方法不更新auto_now的原因与解决方案
status_item = DeployStatus.objects.get(name=status_name)
DeployImage.objects.filter(name=order_name).update(
deploy_status=status_item,
change_date=datetime.now())
# 上面的操作,才会更新DeployImage表里的change_date(add_now=True)的时间,
# 或是如下调用save()方法
# deploy_item = DeployImage.objects.get(name=order_name)
# deploy_item.deploy_status = status_item
# deploy_item.save()
以上关于Django Model中update时auto_now不生效的原因及解决方式的分享到此结束,希望能为开发者提供参考,并欢迎继续支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













