【问题标题】:How to update an m2m field programmatically in django signals如何在 django 信号中以编程方式更新 m2m 字段
【发布时间】:2021-08-22 13:18:35
【问题描述】:

我正在尝试自动更新模型类中的 m2m 字段。如果为真类型,则为观察执行,这意味着如果我的模型实例具有某个属性,则将其分配给该组或该组。 模型类如下所示:

class User(AbstractBaseUser, PermissionsMixin):
    is_worker = models.BooleanField(_('Worker'), default=False, help_text='register as a worker')
    is_client = models.BooleanField(_('Client'), default=False, help_text='register as a client')

信号如下所示:

@receiver(post_save, sender=User)
def assign_user_to_group(sender, instance, **kwargs):
    if instance.is_client:
        instance.groups.add([g.pk for g in Group.objects.filter(name='clients')][0])
    elif instance.is_worker:
        instance.groups.add([g.pk for g in Group.objects.filter(name='workers')][0])

通常,我可能需要在我的实例上调用 save() 方法,但文档另有说明,再加上无视这只会让我 RecursionError。 您能否建议一种最能解决此问题的更清洁的方法?谢谢。

编辑

我最终扩展了模型的 save() 方法,如下所示:

from django.db import transaction


def save(self, force_insert=False, force_update=False, *args, **kwargs):
    instance = super(User, self).save(force_insert, force_update, *args, **kwargs)
    transaction.on_commit(self.update_user_group)
    return instance

def update_user_group(self):
    if self.is_worker:
        self.groups.set([g.pk for g in Group.objects.filter(name='workers')])
    elif self.is_client:
        self.groups.set([g.pk for g in Group.objects.filter(name='clients')])

【问题讨论】:

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


    【解决方案1】:

    您当前的方法出了什么问题?在多对多关系上使用.add() 应该足以更新关系,而无需调用.save()

    您还进行了不必要的列表理解。做Group.objects.filter(name='workers')[0]Group.objects.filter(name='workers').first()就足够了

    【讨论】:

    • 谢谢@PetrMitsel。我用post_save 信号尝试了这个,但是,它并没有像我想的那样将与组相关的对象添加到用户实例中。正如编辑中所述,我最终不得不覆盖我的模型的save()
    • 很高兴它对您有用。我想这里的信号不是绝对必要的,因为您试图覆盖一个模型上的保存行为,而不是创建其他模型实例或做其他不相关的事情。
    猜你喜欢
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多