簡體   English   中英

后保存信號和關系

[英]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')

保存項目時的時間表如下:

  1. Project.save()
  2. PersonProjectMembership.save()

因此,在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.throughhttps://docs.djangoproject.com/zh-CN/1.9/topics/signals /

您可能知道,Many2Many關系是通過附加表存儲的,該表包含關系兩端的主鍵。 因此,與Many2Many關系的保存模型實例是兩個步驟的過程:

  1. 首先,實例被保存:數據庫中的新記錄被創建並且實例接收它的主鍵。 post_save會觸發post_save

  2. 之后,關系被保存:在關系表中創建記錄。 m2m-changed將觸發m2m-changed信號。

換句話說,當post_save被觸發時,尚未處理m2m關系。

您可以檢查文檔: m2m-changed

在深入研究代碼並進行簡單測試之后,我嘗試了krasnoperov建議的m2m_changed信號。 我意識到,如果您明確聲明一個“直通”模型(在本例中為“ PersonProjectMembership”),則此信號將無法正常工作。

然后我再次考慮,並將我的方法鏈接到“ PersonProjectMembership”的post_save信號。 那很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM