Mik*_*keN 152 django django-models
我想在保存新记录(不更新现有记录)时在Django模型对象的save()方法中触发特殊操作.
检查(self.id!= None)是否必要且足以保证自我记录是新的而不是更新?这可能会忽略任何特殊情况?
Dav*_*ith 190
self.pk is None:
Run Code Online (Sandbox Code Playgroud)
在新的Model对象中返回True,除非该对象具有UUIDField
as primary_key
.
您可能需要担心的极端情况是,除id之外的字段是否存在唯一性约束(例如,其他字段上的辅助唯一索引).在这种情况下,您仍然可以拥有新记录,但无法保存.
Sai*_*ail 154
检查self.pk
我们可以检查self._state
模型的替代方法
self._state.adding is True
创建
self._state.adding is False
更新
我从这个页面得到了它
Kay*_*Ess 38
对于检查self.pk == None
是不足够的,以确定该物体将被插入或更新数据库.
Django O/RM有一个特别讨厌的黑客攻击,基本上是检查PK位置是否有东西,如果是,则执行UPDATE,否则执行INSERT(如果PK为None,则优化为INSERT).
它必须这样做的原因是因为您可以在创建对象时设置PK.虽然在主键的序列列的位置不常见,但这不适用于其他类型的主键字段.
如果你真的想知道你必须做O/RM所做的事情并查看数据库.
当然,您的代码中有一个特定的案例,因此很可能会self.pk == None
告诉您需要知道的所有内容,但这不是一般解决方案.
JF *_*mon 10
您可以连接到post_save信号,该信号发送"已创建"的kwargs,如果为true,则表示您的对象已插入.
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
Run Code Online (Sandbox Code Playgroud)
这很方便,因为您新创建的对象(self)具有pk
值
对于即使在您将 aUUIDField
作为主键(正如其他人所指出的,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
Run Code Online (Sandbox Code Playgroud)
此回调将阻塞该save
方法,因此您可以在响应通过线路发回之前执行诸如触发通知或进一步更新模型之类的操作,无论您使用的是表单还是 Django REST 框架进行 AJAX 调用。当然,负责任地使用并将繁重的任务卸载到作业队列,而不是让您的用户等待:)
我这次谈话的时间已经很晚了,但我遇到了一个问题,当self.pk有一个与之关联的默认值时会被填充.
我解决这个问题的方法是在模型中添加一个date_created字段
date_created = models.DateTimeField(auto_now_add=True)
从这里你可以去
created = self.date_created is None
归档时间: |
|
查看次数: |
63495 次 |
最近记录: |