From 3af4fc00223b9d459e284b19f8779457b70e6ec5 Mon Sep 17 00:00:00 2001 From: Jacob Rief Date: Wed, 24 Jul 2024 16:21:17 +0200 Subject: [PATCH 1/2] fix-permissions-adding-page (#419) * fix-permissions-adding-page * Update djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html Co-authored-by: Fabian Braun --------- Co-authored-by: Fabian Braun --- .../templates/admin/djangocms_versioning/page/change_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html b/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html index 92d00d0e..925c1845 100644 --- a/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html +++ b/djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html @@ -32,7 +32,7 @@ -
+ {% csrf_token %} {% block form_top %}{% endblock %} From ad0024c728898200bf91ce8c103a112a73dda4fd Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 26 Jul 2024 11:27:13 +0200 Subject: [PATCH 2/2] chore: Prepare release 2.1.0 (#415) * Prepare release 2.1.0 * Update tests for django-cms@develop-4 * Fix ruff issues * Add warning to `CMSMenu` class --- CHANGELOG.rst | 10 +++ djangocms_versioning/__init__.py | 2 +- djangocms_versioning/cms_menus.py | 14 +++- djangocms_versioning/plugin_rendering.py | 4 +- djangocms_versioning/test_utils/factories.py | 37 +++++++---- tests/test_indicators.py | 3 +- tests/test_integration_with_core.py | 3 +- tests/test_menus.py | 67 ++++++++------------ 8 files changed, 78 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1b54acd2..3b6d6f82 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,16 @@ Changelog ========= +2.1.0 (2024-07-12) +================== + +* feat: Add versioning actions to settings (admin change view) of versioned objects by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/408 +* fix: Remove workaround for page-specific rendering by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/411 +* fix: Compare versions' back button sometimes returns to invalid URL by @fsbraun in https://github.com/django-cms/djangocms-versioning/pull/413 + + +**Full Changelog**: https://github.com/django-cms/djangocms-versioning/compare/2.0.2...2.1.0 + 2.0.2 (2024-05-03) ================== diff --git a/djangocms_versioning/__init__.py b/djangocms_versioning/__init__.py index 0309ae29..9aa3f903 100644 --- a/djangocms_versioning/__init__.py +++ b/djangocms_versioning/__init__.py @@ -1 +1 @@ -__version__ = "2.0.2" +__version__ = "2.1.0" diff --git a/djangocms_versioning/cms_menus.py b/djangocms_versioning/cms_menus.py index e11cb109..51fd54ec 100644 --- a/djangocms_versioning/cms_menus.py +++ b/djangocms_versioning/cms_menus.py @@ -2,6 +2,11 @@ from cms.apphook_pool import apphook_pool from cms.cms_menus import CMSMenu as OriginalCMSMenu, get_visible_nodes from cms.models import Page + +try: + from cms.models import TreeNode +except ImportError: + TreeNode = None from cms.toolbar.utils import get_object_preview_url, get_toolbar_from_request from cms.utils.page import get_page_queryset from django.apps import apps @@ -76,6 +81,11 @@ def _get_attrs_for_node(renderer, page_content): class CMSMenu(Menu): + """This is a legacy class used by django CMS 4.0 and django CMS 4.1.0 only. Its language + fallback mechanism does not comply with django CMS' core's. Also, it is by far slower + than django CMS core's. As of django CMS 4.1.1, this class is by default deactivated. + + See https://discord.com/channels/800813886689247262/1204047551570120755 for more information.""" def get_nodes(self, request): site = self.renderer.site language = self.renderer.request_language @@ -106,8 +116,8 @@ def get_nodes(self, request): versionable_item.content_model._base_manager.filter( language=language, page__in=pages_qs, versions__state__in=states ) - .order_by("page__node__path", "versions__state") - .select_related("page", "page__node") + .order_by("page__node__path" if TreeNode else "page__path", "versions__state") + .select_related("page", "page__node" if TreeNode else "page") .prefetch_related("versions") ) added_pages = [] diff --git a/djangocms_versioning/plugin_rendering.py b/djangocms_versioning/plugin_rendering.py index cad0be24..2ed05652 100644 --- a/djangocms_versioning/plugin_rendering.py +++ b/djangocms_versioning/plugin_rendering.py @@ -43,8 +43,8 @@ def render_plugin(self, instance, context, placeholder=None, editable=False): return super().render_plugin(instance, context, placeholder, editable) if cms_version in ("4.1.0", "4.1.1"): - # Only needed for CMS 4.1.0 and 4.1.1 which have fix #7952 not merged - # With #7952, page-specific rendering works well with versioning. + # Only needed for CMS 4.1.0 and 4.1.1 which have fix #7924 not merged + # With #7924, page-specific rendering works well with versioning. def render_obj_placeholder( self, slot, context, inherit, nodelist=None, editable=True ): diff --git a/djangocms_versioning/test_utils/factories.py b/djangocms_versioning/test_utils/factories.py index 15a8a364..0b62dc59 100644 --- a/djangocms_versioning/test_utils/factories.py +++ b/djangocms_versioning/test_utils/factories.py @@ -2,7 +2,12 @@ import factory from cms import constants -from cms.models import Page, PageContent, PageUrl, Placeholder, TreeNode +from cms.models import Page, PageContent, PageUrl, Placeholder + +try: + from cms.models import TreeNode +except ImportError: + TreeNode = None from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site @@ -170,18 +175,19 @@ def version(self, create, extracted, **kwargs): IncorrectBlogPostVersionFactory(content=self, **kwargs) -class TreeNodeFactory(factory.django.DjangoModelFactory): - site = factory.fuzzy.FuzzyChoice(Site.objects.all()) - depth = 0 - # NOTE: Generating path this way is probably not a good way of - # doing it, but seems to work for our present tests which only - # really need a tree node to exist and not throw unique constraint - # errors on this field. If the data in this model starts mattering - # in our tests then something more will need to be done here. - path = FuzzyText(length=8, chars=string.digits) +if TreeNode: + class TreeNodeFactory(factory.django.DjangoModelFactory): + site = factory.fuzzy.FuzzyChoice(Site.objects.all()) + depth = 0 + # NOTE: Generating path this way is probably not a good way of + # doing it, but seems to work for our present tests which only + # really need a tree node to exist and not throw unique constraint + # errors on this field. If the data in this model starts mattering + # in our tests then something more will need to be done here. + path = FuzzyText(length=8, chars=string.digits) - class Meta: - model = TreeNode + class Meta: + model = TreeNode class PageUrlFactory(factory.django.DjangoModelFactory): @@ -195,7 +201,12 @@ class Meta: class PageFactory(factory.django.DjangoModelFactory): - node = factory.SubFactory(TreeNodeFactory) + if TreeNode: + node = factory.SubFactory(TreeNodeFactory) + else: + site = factory.fuzzy.FuzzyChoice(Site.objects.all()) + depth = 0 + path = FuzzyText(length=8, chars=string.digits) class Meta: model = Page diff --git a/tests/test_indicators.py b/tests/test_indicators.py index 551e3316..f3601bed 100644 --- a/tests/test_indicators.py +++ b/tests/test_indicators.py @@ -11,6 +11,7 @@ BlogPostVersionFactory, PageFactory, PageVersionFactory, + TreeNode, ) @@ -86,7 +87,7 @@ def test_latest_admin_viewable_archive_on_top_of_published(self): class TestVersionState(CMSTestCase): def test_page_indicators(self): """The page content indicators render correctly""" - page = PageFactory(node__depth=1) + page = PageFactory(node__depth=1) if TreeNode else PageFactory(depth=1) version1 = PageVersionFactory( content__page=page, content__language="en", diff --git a/tests/test_integration_with_core.py b/tests/test_integration_with_core.py index a4b8a8bd..8dd9cc1b 100644 --- a/tests/test_integration_with_core.py +++ b/tests/test_integration_with_core.py @@ -9,6 +9,7 @@ PlaceholderFactory, PollVersionFactory, TextPluginFactory, + TreeNode, ) @@ -190,7 +191,7 @@ def test_default_cms_page_changelist_view_language_with_multi_language_content(s language filters / additional grouping values are set using the default CMS PageContent view """ - page = PageFactory(node__depth=1) + page = PageFactory(node__depth=1) if TreeNode else PageFactory(depth=1) en_version1 = PageVersionFactory( content__page=page, content__language="en", diff --git a/tests/test_menus.py b/tests/test_menus.py index a8c02b1a..5340d82d 100644 --- a/tests/test_menus.py +++ b/tests/test_menus.py @@ -19,48 +19,31 @@ class CMSVersionedMenuTestCase(CMSTestCase): def setUp(self): super().setUp() - self._page_1 = PageVersionFactory( - content__title="page_content_1", - content__menu_title="", - content__in_navigation=True, - content__limit_visibility_in_menu=None, - content__language="en", - content__page__node__path="0001", - ) - self._page_2 = PageVersionFactory( - content__title="page_content_2", - content__menu_title="", - content__in_navigation=True, - content__limit_visibility_in_menu=None, - content__language="en", - content__page__node__path="0002", - ) - self._page_2_1 = PageVersionFactory( - content__title="page_content_2_1", - content__menu_title="", - content__in_navigation=True, - content__limit_visibility_in_menu=None, - content__language="en", - content__page__node__path="00020001", - content__page__node__parent=self._page_2.content.page.node, - ) - self._page_2_2 = PageVersionFactory( - content__title="page_content_2_2", - content__menu_title="", - content__in_navigation=True, - content__limit_visibility_in_menu=None, - content__language="en", - content__page__node__path="00020002", - content__page__node__parent=self._page_2.content.page.node, - ) - self._page_3 = PageVersionFactory( - content__title="page_content_3", - content__menu_title="", - content__in_navigation=True, - content__limit_visibility_in_menu=None, - content__language="en", - content__page__node__path="0003", - ) + from djangocms_versioning.test_utils.factories import TreeNode + + def get_page(title, path, parent=None): + return { + "content__title": title, + "content__menu_title": "", + "content__in_navigation": True, + "content__limit_visibility_in_menu": None, + "content__language": "en", + "content__page__node__path" if TreeNode else "content__page__path": path, + "content__page__node__parent" if TreeNode else "content__page__parent": parent, + } + self._page_1 = PageVersionFactory(**get_page("page_content_1", "0001")) + self._page_2 = PageVersionFactory(**get_page("page_content_2", "0002")) + self._page_2_1 = PageVersionFactory(**get_page( + "page_content_2_1", + "00020001", + self._page_2.content.page.node if TreeNode else self._page_2.content.page, + )) + self._page_2_2 = PageVersionFactory(**get_page( + "page_content_2_2", + "00020002", + self._page_2.content.page.node if TreeNode else self._page_2.content.page, + )) + self._page_3 = PageVersionFactory(**get_page("page_content_3", "0003")) def _render_menu(self, user=None, **kwargs): request = RequestFactory().get("/")