Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 信号m2m_已更改,且带有post_的bug已删除_Django_Django Signals - Fatal编程技术网

Django 信号m2m_已更改,且带有post_的bug已删除

Django 信号m2m_已更改,且带有post_的bug已删除,django,django-signals,Django,Django Signals,我需要检测一个post_remove信号,所以我写了: def handler1(sender, instance, action, reverse, model, pk_set, **kwargs): if (action == 'post_remove'): test1() # not declared but make a bug if it works, to detect :) m2m_changed.connect(handler1, sender=Course.subs

我需要检测一个post_remove信号,所以我写了:

def handler1(sender, instance, action, reverse, model, pk_set, **kwargs):
if (action == 'post_remove'):
    test1()  # not declared but make a bug if it works, to detect :)

m2m_changed.connect(handler1, sender=Course.subscribed.through)
如果我将“post\u remove”更改为“post\u add”,则没有问题。。是django关于post_remove的bug吗

我使用该模型,并在“subscribed”的两个值之间切换(因此一个添加,一个删除)


我看到一篇文章有一个django的bug,也许它还没有被修复。。。(或者是我^^)

据我所知,这不是一个bug,只是Django没有以您期望的方式更新m2m关系。它不会删除要删除的关系,然后添加新的关系。相反,它会清除所有m2m关系,然后再次添加它们

有一个相关的问题链接到票

因此,您可以使用
m2m\u changed
信号检查
pre\u clear
post\u clear
操作,但由于这些操作不提供
pk\u set
,因此无法帮助您在保存之前找到相关条目,正如您希望在中所做的。

多亏了我找到了解决方案,并将其发布在这里-也许有人可以使用它

型号.py

class Team(models.Model):
    name = models.CharField(max_length=100)
    members = models.ManyToManyField(User)

pre_save.connect(team_pre_save, sender=Team)
m2m_changed.connect(team_members_changed, sender=Team.members.through)
def team_pre_save(sender, instance, **kwargs):
    if instance.pk:
        instance._old_m2m = set(list(instance.members.values_list('pk', flat=True)))
    else:
        instance._old_m2m = set(list())

def team_members_changed(sender, instance, **kwargs):
    if kwargs['action'] == "post_clear":
        # remove all users from group
        group = Group.objects.get(name='some group')
        for member in instance._old_m2m:
            user = User.objects.get(pk=member)
            user.groups.remove(group)

    if kwargs['action'] == "post_add":
        added_members = list(kwargs['pk_set'].difference(instance._old_m2m))
        deleted_members = list(instance._old_m2m.difference(kwargs['pk_set']))

        if added_members or deleted_members:
            # we got a change - do something, for example add them to a group?
            group = Group.objects.get(name='some group')

            for member in added_members:
                user = User.objects.get(pk=member)
                user.groups.add(group)

            for member in deleted_members:
                user = User.objects.get(pk=member)
                user.groups.remove(group)
信号.py

class Team(models.Model):
    name = models.CharField(max_length=100)
    members = models.ManyToManyField(User)

pre_save.connect(team_pre_save, sender=Team)
m2m_changed.connect(team_members_changed, sender=Team.members.through)
def team_pre_save(sender, instance, **kwargs):
    if instance.pk:
        instance._old_m2m = set(list(instance.members.values_list('pk', flat=True)))
    else:
        instance._old_m2m = set(list())

def team_members_changed(sender, instance, **kwargs):
    if kwargs['action'] == "post_clear":
        # remove all users from group
        group = Group.objects.get(name='some group')
        for member in instance._old_m2m:
            user = User.objects.get(pk=member)
            user.groups.remove(group)

    if kwargs['action'] == "post_add":
        added_members = list(kwargs['pk_set'].difference(instance._old_m2m))
        deleted_members = list(instance._old_m2m.difference(kwargs['pk_set']))

        if added_members or deleted_members:
            # we got a change - do something, for example add them to a group?
            group = Group.objects.get(name='some group')

            for member in added_members:
                user = User.objects.get(pk=member)
                user.groups.add(group)

            for member in deleted_members:
                user = User.objects.get(pk=member)
                user.groups.remove(group)

经过长时间的研究,我得出了一个结论 首先,我的问题是:当我的m2m为空时,我有一些如何从我的模型中更新一个atribute设置为False,如果它至少有一个项目,则设置为true,因此,真正的事情是有效的,但当我尝试“pre_remove”或“post_remove”时,从来没有触发过,所以在尝试了一些不同的示例后,我在这个“pre_clear”上看到了一些奇怪的东西,每次我更改m2m时,它总是有最后一个值,因此我设法从m2m中强制删除该值,这样它会触发pre_remove和post_remove,因此这对我有效,请参见下面的代码

所以现在我可以根据我的m2m自动设置为真或假

class Servico(BaseMixin):
    descricao = models.CharField(max_length=50)

#This inheritance from User of django that has is_active boolean field
class UsuarioRM(Usuario):
    servicos = models.ManyToManyField(Servico,related_name='servicos_usuario', blank=True)

# SIGNALS
from django.db.models import signals
from django.db.models.signals import m2m_changed

def usuariorm_servicos_changed(sender, **kwargs):
    action = kwargs.pop('action', None)
    pk_set = kwargs.pop('pk_set', None)
    instance = kwargs.pop('instance', None)

    if action == "pre_clear":
        if instance.servicos.all():
        servicos = instance.servicos.all()
            for servico in servicos:
                instance.servicos.remove(servico)
            instance.save()
    else:
        instance.is_active = False
        instance.save() 
        if action == "post_add":
            if pk_set:
            instance.is_active = True 
        else:
            instance.is_active = False

        instance.save()

 m2m_changed.connect( usuariorm_servicos_changed, sender=UsuarioRM.servicos.through )

我真的不知道该怎么做我该怎么做。。。我也不能使用信号。save()覆盖。。如果一个用户被从另一个模型的字段(m2m)删除,我需要从一个模型字段(m2m)删除他…我不确定最好的方法是什么。您可以尝试使用
pre\u save
信号将相关对象存储在实例上,例如
instance.\u old\u m2m=list(instance.subscribed.values\u list('pk',flat=True))
。然后在
post\u add
信号的处理程序中,将
pk\u集
实例进行比较。祝你好运