diff --git a/djangocms_alias/models.py b/djangocms_alias/models.py index f56b477..3c99cde 100644 --- a/djangocms_alias/models.py +++ b/djangocms_alias/models.py @@ -133,6 +133,11 @@ def objects_using(self): plugins = self.cms_plugins.select_related("placeholder").prefetch_related("placeholder__source") for plugin in plugins: obj = plugin.placeholder.source + + # Skip plugins that have no placeholder source e.g clipboard + if obj is None: + continue + obj_class_name = obj.__class__.__name__ if obj_class_name.endswith("Content"): attr_name = obj_class_name.replace("Content", "").lower() diff --git a/tests/test_views.py b/tests/test_views.py index d11df34..34ebebc 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -1580,3 +1580,24 @@ def test_view_multilanguage(self): self.assertNotContains(list_response, alias_content_de.name) self.assertNotContains(detail_response, en_plugin.body) self.assertNotContains(list_response, alias.name) + + def test_usage_view_if_alias_is_saved_to_clipboard(self): + """ + The usage view should ignore the clipboard entry + """ + + alias = self._create_alias() + placeholder = Placeholder.objects.create(slot="clipboard") + add_plugin(placeholder, "Alias", language="en", alias=alias) + + with self.login_user_context(self.superuser): + response = self.client.get( + admin_reverse( + USAGE_ALIAS_URL_NAME, + args=[alias.pk], + ), + ) + + self.assertEqual(response.status_code, 200) + # Check that the alias is displayed in the response content + self.assertContains(response, alias.name)