【问题标题】:Can't change m2m relation on model save()无法更改模型 save() 上的 m2m 关系
【发布时间】:2014-06-15 14:50:56
【问题描述】:

我有带有 is_instructor 字段的自定义用户模型,如果此值为 True,我想将用户添加到 Instructors 组。我试图通过覆盖 save() 方法并使用信号来做到这一点,但它们都不起作用。

这不起作用:

class CustomUser(AbstractBaseUser, PermissionsMixin):
    ...
    is_instructor = models.BooleanField(_('instructor'), default=False)
    ...

    def save(self, *args, **kwargs):
        ...
        super(CustomUser, self).save(*args, **kwargs)
        ins_group = Group.objects.get(name='Instructors')
        if self.is_instructor:
            self.groups.add(ins_group)    # No effect
        else:
            self.groups.remove(ins_group) # No effect

同样使用信号(不起作用):

@receiver(post_save, sender=CustomUser)
def update_groups(sender, instance, **kwargs):
    ins_group = Group.objects.get(name='Instructors')
    if instance.is_instructor:
        instance.groups.add(ins_group)    # No effect
    else:
        instance.groups.remove(ins_group) # No effect

虽然在视图中可以正常工作:

def update_user(request, pk, template='userprofile/customuser_form.html'):
    ...
    profile = get_object_or_404(get_user_model(), id=pk)
    if request.method == 'POST':
        form = form_class(request.POST, instance=profile)
        if form.is_valid():
            u = form.save(commit=False)
            ins = Group.objects.get(name='Instructors')
            if u.is_instructor:
                u.groups.add(ins)    # Works
            else:
                u.groups.remove(ins) # Works
            u.save()
            redirect('userprofile:detail', u.pk)
    ...

但我也需要在模型中执行此操作以在管理员中保存用户时更新组。我的代码有什么问题?

【问题讨论】:

  • groups 字段是否包含在ModelForm 中的任何更改?
  • 不,它不包含在表单中。
  • 向我们展示您正在使用的模型表单的定义。

标签: django django-orm


【解决方案1】:

save() 不适用于新实例,因为您尝试在调用 super 之前修改关系。

信号可能根本没有加载。您将它放入哪个模块(希望是models.py?)。检查update_groups 是否在您期望的时候被调用。

附带说明:使用信号时,请记住尊重 raw 关键字参数。

【讨论】:

  • save() 没关系,实际上我在更新组之前确实调用了 super(代替省略号),然后再次保存模型实例。我更新了有问题的代码。至于信号,是的,代码位于 models.py 中,并且在预期时发出信号,我在开发服务器上使用 pdb 进行了检查。 原始参数 -- 你是什么意思?能否提供文档链接?
  • 当然,raw 文档在这里找到:docs.djangoproject.com/en/dev/ref/signals/#post-save 它说:raw A boolean;如果模型完全按照呈现方式保存(即加载夹具时),则为真。不应查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态。很抱歉我错过了第一次超级保存。那你为什么要调用它两次(不是你遇到的特定问题,但仍然让我感到困惑)?
  • 哎呀,你说得对,第一个save()就够了,谢谢指出。更新了代码。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2010-10-22
  • 2016-09-19
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
相关资源
最近更新 更多