nla*_*aux 6 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.subscribed.through)
Run Code Online (Sandbox Code Playgroud)
如果我用'post_add'改变'post_remove'就可以了..这是关于post_remove的django的错误吗?
我使用该模型并在两个'subscribed'值之间切换(所以添加一个,删除一个)
class Course(models.Model):
name = models.CharField(max_length=30)
subscribed = models.ManyToManyField(User, related_name='course_list', blank=True, null=True, limit_choices_to={'userprofile__status': 'student'})
Run Code Online (Sandbox Code Playgroud)
我看过一篇有django错误的帖子,也许它还没有被修复......(或者它是我^^)
据我了解,这不是一个bug,只是Django没有按照你期望的方式更新m2m关系.它不会删除要删除的关系,然后添加新的关系.相反,它清除所有m2m关系,然后再添加它们.
有一个相关的问题Django信号m2m_changed未触发,它链接到票证13087.
因此,您可以使用信号检查 pre_clear或post_clear操作m2m_changed,但由于这些操作不提供pk_set,因此您无法在保存之前找到相关条目,如您在其他问题中所做的那样.
感谢Alasdairs的 评论,我找到了解决方案并将其发布在此处 - 也许有人可以使用它.
models.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)
Run Code Online (Sandbox Code Playgroud)
signals.py
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2302 次 |
| 最近记录: |