diff --git a/waffle/signals.py b/waffle/signals.py index b64cecbf..3087e6c0 100644 --- a/waffle/signals.py +++ b/waffle/signals.py @@ -8,4 +8,12 @@ @receiver(m2m_changed, sender=get_waffle_flag_model().groups.through) def flag_membership_changed(sender, instance, action, **kwargs): if action in ('post_add', 'post_remove'): - instance.flush() + flag_model = get_waffle_flag_model() + + # instance could be a flag or an instance of the related model + # https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed + if isinstance(instance, flag_model): + instance.flush() + else: + for flag in flag_model.objects.filter(pk__in=kwargs['pk_set']): + flag.flush() diff --git a/waffle/tests/test_waffle.py b/waffle/tests/test_waffle.py index cd2c01d4..c246231f 100644 --- a/waffle/tests/test_waffle.py +++ b/waffle/tests/test_waffle.py @@ -164,6 +164,29 @@ def test_user(self): response = process_request(request, views.flag_in_view) self.assertEqual(b'off', response.content) + def test_remove_from_user(self): + """Same operation of `test_user` but performed with reverse relation""" + user = get_user_model().objects.create(username='foo') + flag = waffle.get_waffle_flag_model().objects.create(name='myflag') + flag.users.add(user) + + request = get() + request.user = user + response = process_request(request, views.flag_in_view) + self.assertEqual(b'on', response.content) + assert 'dwf_myflag' not in response.cookies + + request.user = get_user_model().objects.create(username='someone_else') + response = process_request(request, views.flag_in_view) + self.assertEqual(b'off', response.content) + assert 'dwf_myflag' not in response.cookies + + # Unsetting the flag on a user should have an effect. + user.flag_set.remove(flag) + request.user = user + response = process_request(request, views.flag_in_view) + self.assertEqual(b'off', response.content) + def test_group(self): """Test the per-group switch.""" group = Group.objects.create(name='foo') @@ -191,6 +214,33 @@ def test_group(self): response = process_request(request, views.flag_in_view) self.assertEqual(b'off', response.content) + def test_remove_from_group(self): + """Same operation of `test_group` but performed with reverse relation""" + group = Group.objects.create(name='foo') + user = get_user_model().objects.create(username='bar') + user.groups.add(group) + + flag = waffle.get_waffle_flag_model().objects.create(name='myflag') + flag.groups.add(group) + + request = get() + request.user = user + response = process_request(request, views.flag_in_view) + self.assertEqual(b'on', response.content) + assert 'dwf_myflag' not in response.cookies + + request.user = get_user_model()(username='someone_else') + request.user.save() + response = process_request(request, views.flag_in_view) + self.assertEqual(b'off', response.content) + assert 'dwf_myflag' not in response.cookies + + # Unsetting the flag on a group should have an effect. + group.flag_set.remove(flag) + request.user = user + response = process_request(request, views.flag_in_view) + self.assertEqual(b'off', response.content) + def test_authenticated(self): """Test the authenticated/anonymous switch.""" waffle.get_waffle_flag_model().objects.create(name='myflag', authenticated=True)