Django从post_保存信号访问许多字段
我有一个Django模型,我想在保存时或保存后修改对象权限。我已经尝试了一些解决方案,并且Django从post_保存信号访问许多字段,django,django-models,django-signals,Django,Django Models,Django Signals,我有一个Django模型,我想在保存时或保存后修改对象权限。我已经尝试了一些解决方案,并且post_save信号似乎是我想要做的事情的最佳候选者: class Project(models.Model): title = models.CharField(max_length=755, default='default') assigned_to = models.ManyToManyField( User, default=Non
post_save
信号似乎是我想要做的事情的最佳候选者:
class Project(models.Model):
title = models.CharField(max_length=755, default='default')
assigned_to = models.ManyToManyField(
User, default=None, blank=True, null=True
)
created_by = models.ForeignKey(
User,
related_name="%(app_label)s_%(class)s_related"
)
@receiver(post_save, sender=Project)
def assign_project_perms(sender, instance, **kwargs):
print("instance title: "+str(instance.title))
print("instance assigned_to: "+str(instance.assigned_to.all()))
在这种情况下,当创建项目时,信号触发,我看到标题
,但分配给
字段的列表为空
保存后,如何访问分配给数据的已保存的
文件?您不打算这样做。m2m是在保存实例之后保存的,因此在所有m2m更新中不会有任何记录。进一步的问题(即使您解决了这个问题)是,您仍然处于事务中,查询数据库无论如何都无法获得具有正确状态的m2m
解决方案是挂接到m2m\u changed
信号,而不是post\u save
如果您的m2m可以为空(blank=True
),那么您的发送者将被Project.分配到。通过),因为如果m2m未设置,则m2m\u changed
不会触发,所以您的问题不大。您可以通过同时使用post_save
和m2m_changed
来解决此问题。但这种方法有一个很大的缺点——如果m2m字段不是空的,代码将执行两次
因此,您可以使用事务(Django 1.9+)
Django提供了on_commit()
函数来注册回调
事务成功后应执行的功能
承诺
重要提示:此方法仅在代码调用save()
时有效。
post\u save
在仅调用instance.m2m.add()
或instance.m2m.set()
的情况下,信号根本不会触发 您应该使用Concern
作为sender
对象,或者将模型名称改为Project
Concern
实际上是一个抽象基类。现在编辑。我对ForeignKey也有同样的问题,但显然没有信号?+1用于识别发送者(多对多_字段。到)。如果m2m关系没有用显式模型定义,那么它很方便。似乎在管理中没有触发m2m_changed
。对吗?可能与此相关:我尝试过使用on_commit和post save(您编写的最后一个代码),但m2m模型中的更改仍然没有应用。@Daniel可能您的代码根本没有调用save()
,这就是post_save
信号不起作用的原因。
from django.db import transaction
def on_transaction_commit(func):
def inner(*args, **kwargs):
transaction.on_commit(lambda: func(*args, **kwargs))
return inner
@receiver(post_save, sender=SomeModel)
@on_transaction_commit
def my_ultimate_func(sender, **kwargs):
# Do things here