【问题标题】:post_save signal and relationspost_save 信号和关系
【发布时间】:2013-06-13 12:17:43
【问题描述】:

我正在应用 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')

问题是:当我捕捉到保存后信号时,虽然我输入了部门、研究组和员工的值,但它们似乎总是为空。有什么我错过的吗?

更新:低于当前代码,尚未按预期工作。我已将 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/en/1.9/ref/models/fields/#django.db.models.ManyToManyField.throughhttps://docs.djangoproject.com/en/1.9/topics/signals/

【问题讨论】:

  • 你打电话给save_m2m() 吗? docs.djangoproject.com/en/dev/topics/forms/modelforms/… 如果还没有解决,你能显示你保存的视图吗?
  • 嗨 karthikr,感谢您的回答。我正在从 django 管理员那里保存。所以这不应该是问题,我认为:-/
  • 你能展示一下post_signal方法吗?
  • @receiver(m2m_changed, sender=Project.employees.through) def _on_save_project_assign_privileges(sender, instance, action, reverse, model, pk_set, using, **kwargs): [...]跨度>
  • 你搞定了吗?几天前我遇到了同样的问题。如何获取 m2m 字段以及 post_save。 :(

标签: python django django-models django-admin signals


【解决方案1】:

在对我的代码进行了大量挖掘并进行了简单的测试之后,我按照 krasnoperov 的建议尝试了 m2m_changed 信号。我意识到,如果您明确声明“直通”模型(在我的例子中为“PersonProjectMembership”),此信号将无法正常工作。

然后我又想了想,将我的方法与“PersonProjectMembership”的 post_save 信号联系起来。效果很好。

【讨论】:

    【解决方案2】:

    您可能知道,Many2Many 关系是通过附加表存储的,其中包含关系两端的主键。因此,使用 Many2Many 关系保存模型实例是两个步骤:

    1. 首先,保存实例:在数据库中创建新记录,实例接收它的主键。 post_save 此刻被解雇了。

    2. 之后,关系被保存:关系表中的记录被创建。此时会触发m2m-changed 信号。

    换句话说,当post_save 被触发时,m2m 关系尚未处理。

    您可以查看文档:m2m-changed

    【讨论】:

    • 感谢 krasnoperov,但这似乎不起作用@receiver(m2m_changed, sender=Project.employees.through) def _on_save_project_assign_privileges(sender, instance, action, reverse, model, pk_set, using, * *kwargs):
    猜你喜欢
    • 2011-01-24
    • 2016-05-04
    • 1970-01-01
    • 2021-10-26
    • 2023-03-24
    • 1970-01-01
    • 2017-04-06
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多