我正在应用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')
问题是:当我捕获保存后信号时,虽然我输入了部门的值,但研究组和研究组也是如此.员工,他们似乎总是空虚的.有什么我错过的吗?
更新:当前代码下方,尚未按预期工作.我已经用m2m_changed更改了post_save.
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.save()
> PersonProjectMembership.save()
因此,在Project.post_save员工仍然是空的时候是正常的.我要做的就是收听PersonProjectMembership post_save信号:
@receiver(post_save, sender=PersonProjectMembership)
def my_listener(**kwargs):
# do stuff [...]
查看https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.ManyToManyField.through和https://docs.djangoproject.com/en/1.9/topics/signals/
最佳答案 您可能知道,Many2Many关系是通过附加表存储的,其中包含来自关系两端的主键.因此,使用Many2Many关系保存模型实例是两个步骤:
>首先,实例是保存:创建数据库中的新记录,实例接收它的主键. post_save此时被解雇了.
>之后,保存关系:创建关系表中的记录.此时正在发射m2m变化的信号.
换句话说,当触发post_save时,还没有处理m2m关系.
您可以查看文档:m2m-changed