Dar*_*ech 29 django django-signals django-models
我有一个Django模型,我想在保存后或刚刚保存后修改对象权限.我尝试了一些解决方案,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()))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,创建项目时,信号会触发,我会看到title该assigned_to字段的空列表.
保存后如何访问保存的assigned_to数据?
Yuj*_*ita 39
你不会.保存实例后会保存M2M,因此在所有m2m更新中都不会有任何记录.进一步的问题(即使你解决了)是你仍然在交易中,并且查询数据库无论如何都不会让你获得正确的状态.
解决方案是挂钩m2m_changed信号而不是post_save.
https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
那么你的发件人就是 Project.assigned_to.through
Mar*_*hyn 11
如果你的m2m可能是空的(blank=True)你有点麻烦m2m_changed,因为m2m_changed如果没有设置m2m就不会触发.您可以通过使用解决这个问题post_save,并m2m_changed在同一时间.但是这个方法有一个很大的缺点 - 如果m2m字段不为空,你的代码将被执行两次.
所以,你可以使用事务的on_commit(只有Django> = 1.9)
Django提供了on_commit()函数来注册应该在成功提交事务后执行的回调函数.
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_untimate_func(sender, **kwargs):
# Do things here
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10500 次 |
| 最近记录: |