[英]post_save signal and relations
我正在應用post_save信號來為每個對象應用用戶權限,然后相應地過濾查詢集。
我的模型是這樣的:
class Project(models.Model):
# Relations with other entities.
employees = models.ManyToManyField('staff.Person', through='project.PersonProjectMembership',
related_name='projects')
research_groups = models.ManyToManyField('group.Group', related_name='projects',
through='project.ProjectGroupMembership')
departments = models.ManyToManyField('department.Department', related_name='projects',
through='project.ProjectDepartmentMembership')
問題是:當我收到保存后的信號時,盡管我已經輸入了部門,research_groups和員工的值,但它們似乎總是空着的。 有什么我想念的嗎?
更新:在當前代碼下方,該代碼尚未按預期運行。 我已將post_save更改為m2m_changed。
from django.db.models.signals import m2m_changed
from django.db import models
from django.dispatch.dispatcher import receiver
class Project(models.Model):
employees = models.ManyToManyField('staff.Person', through='project.PersonProjectMembership',
related_name='projects')
class PersonProjectMembership(models.Model):
project = models.ForeignKey('project.Project', related_name="person_memberships")
person = models.ForeignKey('staff.Person', related_name="project_memberships")
lead = models.BooleanField(default=False)
position = models.CharField(max_length=50)
project_manager = models.BooleanField(
default=False
)
class Meta:
permissions = (
('view_personprojectmembership', _('View person project membership')),
)
@receiver(m2m_changed, sender=Project.employees.through)
def _on_save_project_assign_privileges(sender, instance, action, reverse, model, pk_set, using, **kwargs):
# [...]
解
在我的項目模型中,我明確將PersonProjectMembership定義為m2m關系雇員的中間模型:
class Project(models.Model):
# Relations with other entities.
employees = models.ManyToManyField('staff.Person', through='project.PersonProjectMembership', related_name='projects')
保存項目時的時間表如下:
因此,在Project.post_save上員工仍然為空是正常的。 我要做的就是聽PersonProjectMembership post_save信號:
@receiver(post_save, sender=PersonProjectMembership)
def my_listener(**kwargs):
# do stuff [...]
查看https://docs.djangoproject.com/zh-CN/1.9/ref/models/fields/#django.db.models.ManyToManyField.through和https://docs.djangoproject.com/zh-CN/1.9/topics/signals /
您可能知道,Many2Many關系是通過附加表存儲的,該表包含關系兩端的主鍵。 因此,與Many2Many關系的保存模型實例是兩個步驟的過程:
首先,實例被保存:數據庫中的新記錄被創建並且實例接收它的主鍵。 post_save
會觸發post_save
。
之后,關系被保存:在關系表中創建記錄。 m2m-changed
將觸發m2m-changed
信號。
換句話說,當post_save
被觸發時,尚未處理m2m關系。
您可以檢查文檔: m2m-changed
在深入研究代碼並進行簡單測試之后,我嘗試了krasnoperov建議的m2m_changed信號。 我意識到,如果您明確聲明一個“直通”模型(在本例中為“ PersonProjectMembership”),則此信號將無法正常工作。
然后我再次考慮,並將我的方法鏈接到“ PersonProjectMembership”的post_save信號。 那很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.