我想在保存新记录(而不是更新现有记录)时,在Django模型对象的save()方法中触发一个特殊操作。
是检查(self。id != None)有必要且充分地保证自我记录是新的且没有被更新?有没有可能被忽略的特殊情况?
我想在保存新记录(而不是更新现有记录)时,在Django模型对象的save()方法中触发一个特殊操作。
是检查(self。id != None)有必要且充分地保证自我记录是新的且没有被更新?有没有可能被忽略的特殊情况?
更新:与本人澄清。_state不是私有实例变量,但这样命名是为了避免冲突,检查self._state。加法现在是更好的检查方法。
self.pk is None:
在一个新的Model对象中返回True,除非对象有一个UUIDField作为它的主键。
您可能不得不担心的极端情况是,除了id之外的字段是否存在唯一性约束(例如,其他字段上的次要惟一索引)。在这种情况下,您可能仍然拥有一条新记录,但无法保存它。
check for self。pk == None不足以确定对象是否将被插入或更新到数据库中。
Django O/RM有一个特别讨厌的hack,基本上就是检查在PK位置是否有东西,如果有就做一个UPDATE,否则就做一个INSERT(如果PK为None,这将被优化为INSERT)。
它必须这样做的原因是允许在创建对象时设置PK。虽然在主键有序列列的地方不常见,但这不适用于其他类型的主键字段。
如果你真的想知道,你必须做O/RM所做的,并在数据库中查找。
当然,在代码中有一个特定的情况,很可能是self。pk == None告诉你所有你需要知道的,但它不是一个通解。
要知道您是在更新还是插入对象(数据),请在表单中使用self.instance.fieldname。在表单中定义一个干净的函数,并检查当前值项是否与前一个值项相同,如果不是,则更新它。
自我。Instance和self.instance.fieldname与新值进行比较
你可以连接到post_save信号,发送一个“创建”kwargs,如果为真,你的对象已经插入。
http://docs.djangoproject.com/en/stable/ref/signals/#post-save
检查self。Id和force_insert标志。
if not self.pk or kwargs.get('force_insert', False):
self.created = True
# call save method.
super(self.__class__, self).save(*args, **kwargs)
#Do all your post save actions in the if block.
if getattr(self, 'created', False):
# So something
# Do something else
这很方便,因为您新创建的对象(self)具有它的pk值
我很晚才谈这个话题,但我遇到了自我的问题。当Pk具有与之关联的默认值时,将填充它。
我解决这个问题的方法是在模型中添加一个date_created字段
date_created = models.DateTimeField(auto_now_add=True)
你可以从这里出发
Created = self。date_created为None
检查自我的另一种方法。我们可以检查self。模型的状态
self._state。添加才是真正的创造
self._state。添加是错误的更新
我是从这一页上得到的
对于一个解决方案,即使你有一个UUIDField作为主键(正如其他人所注意到的,如果你只是覆盖save,它也不是None),你也可以插入Django的post_save信号。将此添加到models.py中:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=MyModel)
def mymodel_saved(sender, instance, created, **kwargs):
if created:
# do extra work on your instance, e.g.
# instance.generate_avatar()
# instance.send_email_notification()
pass
这个回调会阻塞save方法,所以你可以做一些事情,比如触发通知或在响应通过网络发送回之前进一步更新模型,无论你是使用表单还是Django REST框架进行AJAX调用。当然,要负责任地使用,并将繁重的任务卸载到作业队列中,而不是让用户等待:)
这是否适用于上述所有场景?
if self.pk is not None and <ModelName>.objects.filter(pk=self.pk).exists():
...
> def save_model(self, request, obj, form, change):
> if form.instance._state.adding:
> form.instance.author = request.user
> super().save_model(request, obj, form, change)
> else:
> obj.updated_by = request.user.username
>
> super().save_model(request, obj, form, change)
在python 3和django 3中,这是在我的项目中工作的:
def save_model(self, request, obj, form, change):
if not change:
#put your code here when adding a new object.