您可以使用这个 mixin,它可以用于检测模型实例中哪些字段已经发生了变化,并将这些信息传递给保存方法。以下是该 mixin 的描述:
- init 方法中,mixin 初始化一个名为 old_instance_data 的字典,其中存储了模型实例中字段的初始值。
- 在保存方法中,mixin 将当前字段的值与存储在 old_instance_data 中的初始值进行比较,以确定哪些字段已经发生了变化。它创建一个包含已更改字段名称的 update_fields 集合。
- 如果模型实例具有主键(self.pk 不为 None),且未显式提供 update_fields,则 mixin 会自动确定已更改的字段。
- mixin 然后调用父类的保存方法,并将 update_fields 和可能提供的其他关键字参数一起传递给它。
- 如果在保存时传递自己的 update_fields 参数,它将使用该参数。因此,您可以在代码的任何地方部分使用其他 update_fields。
通过在模型中使用这个 mixin,您可以方便地跟踪和保存仅已修改的字段,这对于优化数据库更新和减少不必要的数据库查询非常有帮助。
from django.db import models
class UpdateFieldsMixin(models.Model):
""" Detects which field changed and passes it to save method """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
fields = (field.name for field in self._meta.fields)
self.old_instance_data = {name: getattr(self, name, None)
for name in fields}
def save(self, update_fields=None, **kwargs):
if self.pk:
update_fields = update_fields or {
k for k, v in self.old_instance_data.items()
if getattr(self, k, None) != v}
return super().save(update_fields=update_fields, **kwargs)
class Meta:
abstract = True
使用方法如下:
class YourModel(UpdateFieldsMixin, models.Model):
def save(**kwargs):
return super().save(**kwargs)
那就这样了。如果你有自定义的保存方法,请确保调用UpdateFieldsMixin.save。我建议像上面的例子一样使用super()。
.update()
看起来已经被弃用,但是截至Django 4.0,这两种更新方法仍然可用且未被弃用。非常好的回答,因为提到了两种选项 :-) - ingofreyerauto_now
字段modified_at = models.DateTimeField(auto_now=True)
必须像下面这样指定survey.save(update_fields=["active", "modified_at"])
- Mohamed Jaleel Nazirauto_now
字段modified_at = models.DateTimeField(auto_now=True)
必须像下面这样指定survey.save(update_fields=["active", "modified_at"])
- Mohamed Jaleel Nazir