我有一个相当复杂的Django模型,其中包含一些只能在某些情况下保存的字段.举个简单的例子,
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=200)
counter = models.IntegerField(default=0)
def increment_counter(self):
self.counter = models.F('counter') + 1
self.save(update_fields=['counter'])
Run Code Online (Sandbox Code Playgroud)
这里我使用F表达式来增加计数器时避免竞争条件.我通常永远不会想要将increment_counter函数的值保存在函数之外,因为这可能会撤消从另一个线程或进程调用的增量.
所以问题是,在模型的保存功能中,默认情况下排除某些字段的最佳方法是什么?我尝试了以下内容
def save(self, **kwargs):
if update_fields not in kwargs:
update_fields = set(self._meta.get_all_field_names())
update_fields.difference_update({
'counter',
})
kwargs['update_fields'] = tuple(update_fields)
super().save(**kwargs)
Run Code Online (Sandbox Code Playgroud)
但结果是ValueError: The following fields do not exist in this model or are m2m fields: id.我当然可以id在差异更新中添加和任何m2m字段,但这开始看起来像一个不可维护的混乱,特别是一旦其他模型开始引用这个,这将添加self._meta.get_all_field_names()需要排除的其他名称update_fields.
对于它的价值,我主要需要这个功能来与django管理站点进行交互; 代码中的每个其他位置都可以相对轻松地调用model_obj.save()正确的update_fields.