diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index 5057bdf..36df49b 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -203,13 +203,22 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, sites = self.get_restricted_sites(request) if sites.exists(): qs = qs.filter(sites__in=sites.all()) - return qs + return qs.distinct() def save_related(self, request, form, formsets, change): + if self.get_restricted_sites(request).exists(): + if 'sites' in form.cleaned_data: + form_sites = form.cleaned_data.get('sites', []) + removed = set( + self.get_restricted_sites(request).all() + ).difference(form_sites) + diff_original = set( + form.instance.sites.all() + ).difference(removed).union(form_sites) + form.cleaned_data['sites'] = diff_original + else: + form.cleaned_data['sites'] = self.get_restricted_sites(request).all() super(PostAdmin, self).save_related(request, form, formsets, change) - obj = form.instance - sites = self.get_restricted_sites(request) - obj.sites = sites.all() class Media: css = { diff --git a/tests/base.py b/tests/base.py index ce97827..9fdf7ce 100644 --- a/tests/base.py +++ b/tests/base.py @@ -139,6 +139,7 @@ class BaseTest(BaseTestCase): cls.category_1.name = 'categoria 1' cls.category_1.save() cls.site_2 = Site.objects.create(domain='http://example2.com', name='example 2') + cls.site_3 = Site.objects.create(domain='http://example3.com', name='example 3') cache.clear() @classmethod diff --git a/tests/test_models.py b/tests/test_models.py index a30a274..d019a79 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -314,6 +314,76 @@ class AdminTest(BaseTest): modified_post = Post.objects.language('en').get(pk=post.pk) self.assertEqual(modified_post.safe_translation_getter('post_text'), data['post_text']) + def test_admin_site(self): + pages = self.get_pages() + post = self._get_post(self._post_data[0]['en']) + + # no restrictions, sites are assigned + with self.login_user_context(self.user): + data = {'sites': [1, 2], 'title': 'some title', 'app_config': 1} + request = self.post_request(pages[0], 'en', user=self.user, data=data, path='/en/') + self.assertEquals(post.sites.count(), 0) + msg_mid = MessageMiddleware() + msg_mid.process_request(request) + post_admin = admin.site._registry[Post] + response = post_admin.change_view(request, str(post.pk)) + self.assertEqual(response.status_code, 302) + post = self.reload_model(post) + self.assertEquals(post.sites.count(), 2) + + # user only allowed on 2 sites, can add both + self.user.sites.add(self.site_2) + self.user.sites.add(self.site_3) + post = self.reload_model(post) + with self.login_user_context(self.user): + data = {'sites': [2, 3], 'title': 'some title', 'app_config': 1} + request = self.post_request(pages[0], 'en', user=self.user, data=data, path='/en/') + self.assertEquals(post.sites.count(), 2) + msg_mid = MessageMiddleware() + msg_mid.process_request(request) + post_admin = admin.site._registry[Post] + post_admin._sites = None + response = post_admin.change_view(request, str(post.pk)) + self.assertEqual(response.status_code, 302) + post = self.reload_model(post) + self.assertEquals(post.sites.count(), 3) + self.user.sites.clear() + + # user only allowed on 2 sites, can remove one of his sites + self.user.sites.add(self.site_2) + self.user.sites.add(self.site_3) + with self.login_user_context(self.user): + data = {'sites': [3], 'title': 'some title', 'app_config': 1} + request = self.post_request(pages[0], 'en', user=self.user, data=data, path='/en/') + self.assertEquals(post.sites.count(), 3) + msg_mid = MessageMiddleware() + msg_mid.process_request(request) + post_admin = admin.site._registry[Post] + post_admin._sites = None + response = post_admin.change_view(request, str(post.pk)) + self.assertEqual(response.status_code, 302) + post = self.reload_model(post) + self.assertEquals(post.sites.count(), 2) + self.user.sites.clear() + + # user only allowed on 2 sites, if given sites is empty, the site with no permission on + # is kept + self.user.sites.add(self.site_2) + self.user.sites.add(self.site_3) + with self.login_user_context(self.user): + data = {'sites': [], 'title': 'some title', 'app_config': 1} + request = self.post_request(pages[0], 'en', user=self.user, data=data, path='/en/') + self.assertEquals(post.sites.count(), 2) + msg_mid = MessageMiddleware() + msg_mid.process_request(request) + post_admin = admin.site._registry[Post] + post_admin._sites = None + response = post_admin.change_view(request, str(post.pk)) + self.assertEqual(response.status_code, 302) + post = self.reload_model(post) + self.assertEquals(post.sites.count(), 1) + self.user.sites.clear() + def test_admin_clear_menu(self): """ Tests that after changing apphook config menu structure the menu content is different: new