当我保存新记录(不更新现有记录)时,我想在Django模型对象的save()方法中触发一个特殊操作。
检查(self.id!= None)是否必要且足以保证自我记录是新的而不是更新?这可能会忽略任何特殊情况吗?
答案 0 :(得分:176)
self.pk is None:
在新的Model对象中返回True,除非该对象的UUIDField
为primary_key
。
您可能需要担心的极端情况是,除id之外的字段是否存在唯一性约束(例如,其他字段上的辅助唯一索引)。在这种情况下,您仍然可以手头有新记录,但无法保存。
答案 1 :(得分:128)
检查self.pk
的其他方式我们可以检查模型的self._state
self._state.adding is True
创建
self._state.adding is False
正在更新
我从page
获得了它答案 2 :(得分:42)
检查self.id
假设id
是模型的主键。更通用的方法是使用pk shortcut。
is_new = self.pk is None
答案 3 :(得分:38)
对self.pk == None
的检查不足以确定是否要在数据库中插入或更新对象。
Django O / RM有一个特别讨厌的黑客,基本上是检查PK位置是否有东西,如果是这样做UPDATE,否则执行INSERT(如果PK为None,则优化为INSERT)
之所以这样做是因为您可以在创建对象时设置PK。虽然在主键的序列列中不常见,但这不适用于其他类型的主键字段。
如果您真的想知道您必须执行O / RM所做的事情并查看数据库。
当然,您的代码中有一个特定的案例,因此self.pk == None
很可能会告诉您所有需要知道的内容,但它不是一般解决方案。< / p>
答案 4 :(得分:8)
您可以连接到发送“已创建”的kwargs的post_save信号,如果为true,则表示您的对象已插入。
http://docs.djangoproject.com/en/stable/ref/signals/#post-save
答案 5 :(得分:7)
检查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
值
答案 6 :(得分:5)
我对这个对话已经很晚了,但是我遇到了一个问题,当self.pk有一个与之关联的默认值时会填充它。
我解决这个问题的方法是在模型中添加date_created字段
date_created = models.DateTimeField(auto_now_add=True)
从这里你可以去
created = self.date_created is None
答案 7 :(得分:3)
而是使用 pk 而不是 id :
if not self.pk:
do_something()
答案 8 :(得分:3)
对于即使您将UUIDField
作为主键(如果您只是覆盖None
而其他人已注明不是save
)也可以使用的解决方案插入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调用。当然,负责任地使用并将繁重的任务卸载到作业队列而不是让用户等待:)
答案 9 :(得分:1)
这是常用的方法。
在第一次保存到db
时会给出id答案 10 :(得分:0)
在以上所有情况下都可以使用吗?
if self.pk is not None and <ModelName>.objects.filter(pk=self.pk).exists():
...
答案 11 :(得分:0)
> 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)
答案 12 :(得分:-3)
要知道您是要更新还是插入对象(数据),请在表单中使用self.instance.fieldname
。在表单中定义一个干净的函数,并检查当前值条目是否与前一个相同,如果不是,则更新它。
self.instance
和self.instance.fieldname
与新值进行比较