【发布时间】:2011-05-24 20:39:31
【问题描述】:
(Django 1.1) 我有一个使用 m2m 字段跟踪其成员的项目模型。它看起来像这样:
class Project(models.Model):
members = models.ManyToManyField(User)
sales_rep = models.ForeignKey(User)
sales_mgr = models.ForeignKey(User)
project_mgr = models.ForeignKey(User)
... (more FK user fields) ...
创建项目时,会将选定的sales_rep、sales_mgr、project_mgr 等Users 添加到成员中,以便更轻松地跟踪项目权限。到目前为止,这种方法效果很好。
我现在处理的问题是当User FK 字段之一通过管理员更新时如何更新项目的成员资格。我尝试了各种解决方案来解决这个问题,但最干净的方法似乎是post_save 信号,如下所示:
def update_members(instance, created, **kwargs):
"""
Signal to update project members
"""
if not created: #Created projects are handled differently
instance.members.clear()
members_list = []
if instance.sales_rep:
members_list.append(instance.sales_rep)
if instance.sales_mgr:
members_list.append(instance.sales_mgr)
if instance.project_mgr:
members_list.append(instance.project_mgr)
for m in members_list:
instance.members.add(m)
signals.post_save.connect(update_members, sender=Project)
但是,即使我通过管理员更改了其中一个字段,Project 仍然具有相同的成员!我已经成功地在其他项目中使用我自己的视图更新了成员 m2m 字段,但我也不必让它与管理员一起玩得很好。
除了 post_save 信号来更新会员资格之外,我还应该采取其他方法吗?提前感谢您的帮助!
更新:
澄清一下,当我在前端保存自己的表单时,post_save 信号可以正常工作(旧成员被删除,新成员被添加)。但是,当我通过管理员保存项目时,post_save 信号无法正常工作(成员保持不变)。
我认为 Peter Rowell 的诊断在这种情况下是正确的。如果我从管理员表单中删除“成员”字段,则 post_save 信号可以正常工作。当包含该字段时,它会根据保存时表单中存在的值保存旧成员。无论我在保存项目时对成员 m2m 字段进行什么更改(无论是信号还是自定义保存方法),它都将始终被保存之前表单中存在的成员覆盖。感谢您指出这一点!
【问题讨论】:
-
我不知道这是否是您的问题,但我有一种直觉,您可能遇到了表单代码如何更新 m2m 信息的工件。基本上,他们首先保存主要对象,然后通过首先清除所有对象来设置 m2m 值,然后根据表单中存在的值设置它们。这发生在 主对象上的 save() 之后,因此您在 save() 中或基于
post_save信号所做的任何事情都首先完成,然后 撤消 .这是django.forms.models.save_instance()。如果有after_form_save信号就好了。 -
谢谢,彼得!我相信你的诊断是正确的。我更新了我的原始帖子以包含此信息。
-
彼得是对的。我遇到了同样的问题并找到了解决方法,但它不像“after_form_save”信号那样简洁:stackoverflow.com/questions/3652585/…
-
把我的培根救了下来!在过去的 30 分钟里,我一直在努力解决这个问题。谢谢!
标签: django django-admin membership