Skip to content

Commit 5e155c0

Browse files
authored
Merge branch 'master' into fix/no-double-preview-button
2 parents 185e7a6 + bf89036 commit 5e155c0

File tree

11 files changed

+73
-34
lines changed

11 files changed

+73
-34
lines changed

.github/workflows/docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
python-version: '3.11'
2020
cache: 'pip'
2121
- name: Cache dependencies
22-
uses: actions/[email protected].0
22+
uses: actions/[email protected].2
2323
with:
2424
path: ~/.cache/pip
2525
key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.txt') }}
@@ -44,7 +44,7 @@ jobs:
4444
python-version: '3.11'
4545
cache: 'pip'
4646
- name: Cache dependencies
47-
uses: actions/[email protected].0
47+
uses: actions/[email protected].2
4848
with:
4949
path: ~/.cache/pip
5050
key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.txt') }}

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ jobs:
149149
strategy:
150150
fail-fast: false
151151
matrix:
152-
python-version: ['3.11']
152+
python-version: ['3.12']
153153
requirements-file: ['dj51_cms41.txt']
154154
cms-version: [
155155
'https://github.com/django-cms/django-cms/archive/develop-4.tar.gz'

djangocms_versioning/cms_config.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import collections
22

3+
from cms import __version__ as cms_version
34
from cms.app_base import CMSAppConfig, CMSAppExtension
45
from cms.extensions.models import BaseExtension
56
from cms.models import PageContent, Placeholder
@@ -22,6 +23,7 @@
2223
from django.utils.encoding import force_str
2324
from django.utils.functional import cached_property
2425
from django.utils.translation import gettext_lazy as _
26+
from packaging.version import Version as PackageVersion
2527

2628
from . import indicators
2729
from .admin import VersioningAdminMixin
@@ -393,6 +395,7 @@ class VersioningCMSConfig(CMSAppConfig):
393395
content_admin_mixin=VersioningCMSPageAdminMixin,
394396
)
395397
]
396-
cms_toolbar_mixin = CMSToolbarVersioningMixin
398+
if PackageVersion(cms_version) < PackageVersion("4.2"):
399+
cms_toolbar_mixin = CMSToolbarVersioningMixin
397400
PageContent.add_to_class("is_editable", is_editable)
398401
PageContent.add_to_class("content_indicator", indicators.content_indicator)

djangocms_versioning/cms_toolbars.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from cms.cms_toolbars import (
77
ADD_PAGE_LANGUAGE_BREAK,
88
LANGUAGE_MENU_IDENTIFIER,
9+
BasicToolbar,
910
PageToolbar,
1011
PlaceholderToolbar,
1112
)
@@ -243,7 +244,7 @@ def _get_published_page_version(self):
243244

244245
return PageContent._original_manager.filter(
245246
page=self.page, language=language, versions__state=PUBLISHED
246-
).first()
247+
).select_related("page").first()
247248

248249
def _add_view_published_button(self):
249250
"""Helper method to add a publish button to the toolbar
@@ -321,7 +322,6 @@ def populate(self):
321322
self.page_content = self.get_page_content() if self.page else None
322323
self.permissions_activated = get_cms_setting("PERMISSION")
323324

324-
self.override_language_menu()
325325
self.change_admin_menu()
326326
self.add_page_menu()
327327
self.change_language_menu()
@@ -402,8 +402,9 @@ def change_language_menu(self):
402402
url = add_url_parameters(translation_delete_url, language=code)
403403
on_close = REFRESH_PAGE
404404
if self.toolbar.get_object() == pagecontent and not disabled:
405-
other_content = next((self.page.get_admin_content(lang)for lang in self.page.get_languages()
406-
if lang != pagecontent.language and lang in languages), None)
405+
other_content = next(
406+
(self.page.get_admin_content(lang) for lang in self.page.get_languages()
407+
if lang != pagecontent.language and lang in languages), None)
407408
on_close = get_object_preview_url(other_content)
408409
remove_plugins_menu.add_modal_item(name, url=url, disabled=disabled, on_close=on_close)
409410

@@ -433,10 +434,31 @@ def change_language_menu(self):
433434
)
434435

435436

437+
class VersioningBasicToolbar(BasicToolbar):
438+
def add_language_menu(self):
439+
"""
440+
Originally did override the default language menu for pages that are versioned.
441+
Now creates the menu from scratch, since VersiongBasicToolbar prevents the
442+
core from creating the too generic default language menu.
443+
"""
444+
if not settings.USE_I18N or not self.request.current_page:
445+
# Only add if no page is shown
446+
super().add_language_menu()
447+
return
448+
449+
language_menu = self.toolbar.get_or_create_menu(
450+
LANGUAGE_MENU_IDENTIFIER, _("Language"), position=-1
451+
)
452+
for code, name in get_language_tuple(self.current_site.pk):
453+
# Get the page content, it could be draft too!
454+
page_content = self.page.get_admin_content(language=code)
455+
if page_content:
456+
url = get_object_preview_url(page_content, code)
457+
language_menu.add_link_item(name, url=url, active=self.current_lang == code)
458+
459+
436460
def replace_toolbar(old, new):
437-
"""Replace `old` toolbar class with `new` class,
438-
while keeping its position in toolbar_pool.
439-
"""
461+
"""Replace `old` toolbar class with `new` class, while keeping its position in toolbar_pool."""
440462
new_name = ".".join((new.__module__, new.__name__))
441463
old_name = ".".join((old.__module__, old.__name__))
442464
toolbar_pool.toolbars = OrderedDict(
@@ -447,3 +469,4 @@ def replace_toolbar(old, new):
447469

448470
replace_toolbar(PageToolbar, VersioningPageToolbar)
449471
replace_toolbar(PlaceholderToolbar, VersioningToolbar)
472+
replace_toolbar(BasicToolbar, VersioningBasicToolbar)

djangocms_versioning/datastructures.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ def content_types(self):
176176

177177

178178
class PolymorphicVersionableItem(VersionableItem):
179-
"""VersionableItem for use by base polymorphic class
180-
(for example filer.File).
179+
"""VersionableItem for use by base polymorphic class (for example filer.File).
181180
"""
182181

183182
def _get_content_types(self):

djangocms_versioning/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def get_for_content(self, content_object):
5151
version = self.get(
5252
object_id=content_object.pk, content_type__in=versionable.content_types
5353
)
54+
version._state.fields_cache["content"] = content_object
5455
content_object._version_cache = version
5556
return version
5657

@@ -243,7 +244,11 @@ def convert_to_proxy(self):
243244
"""Returns a copy of current Version object, but as an instance
244245
of its correct proxy model"""
245246

247+
cache = self._state.fields_cache
248+
del self._state.fields_cache # Remove cache before creating deep copy
246249
new_obj = copy.deepcopy(self)
250+
new_obj._state.fields_cache = cache # Recover caches
251+
self._state.fields_cache = cache # Recover caches
247252
new_obj.__class__ = self.versionable.version_model_proxy
248253
return new_obj
249254

djangocms_versioning/plugin_rendering.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from functools import lru_cache
21

32
from cms import __version__ as cms_version
43
from cms.plugin_rendering import ContentRenderer, StructureRenderer
54
from cms.utils.placeholder import rescan_placeholders_for_obj
5+
from django.utils.functional import cached_property
66

77
from . import versionables
88
from .constants import DRAFT, PUBLISHED
@@ -77,12 +77,10 @@ def render_plugin(self, instance, page=None):
7777

7878

7979
class CMSToolbarVersioningMixin:
80-
@property
81-
@lru_cache(16)
80+
@cached_property
8281
def content_renderer(self):
8382
return VersionContentRenderer(request=self.request)
8483

85-
@property
86-
@lru_cache(16)
84+
@cached_property
8785
def structure_renderer(self):
8886
return VersionStructureRenderer(request=self.request)

pyproject.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.ruff]
2-
exclude = [
2+
extend-exclude = [
33
".eggs",
44
".git",
55
".mypy_cache",
@@ -13,25 +13,24 @@ exclude = [
1313
line-length = 120
1414

1515
[tool.ruff.lint]
16-
# https://beta.ruff.rs/docs/configuration/
1716
select = [
1817
"E", # pycodestyle errors
1918
"W", # pycodestyle warnings
2019
"F", # pyflakes
2120
"I", # isort
2221
"C", # flake8-comprehensions
2322
"B", # flake8-bugbear
24-
"Q", # flake8-quotes
23+
"Q", # flake8-quotes
2524
"PLE", # pylint error
2625
"PLR", # pylint refactor
2726
"PLW", # pylint warning
28-
"UP", # pyupgrade
27+
"UP", # pyupgrade
2928
]
3029

31-
ignore = [
30+
extend-ignore = [
3231
"B006", # Do not use mutable data structures for argument defaults
3332
"B011", # tests use assert False
34-
"B019", # Use of `functools.lru_cache` or `functools.cache` on methods can lead to memory leaks
33+
"B019", # Use of `functools.lru_cache` on methods can lead to memory leaks
3534
"B905", # `zip()` without an explicit `strict=` parameter
3635
"C901", # too complex functions
3736
"E402", # module level import not at top of file
@@ -44,6 +43,10 @@ ignore = [
4443
"UP007", # Use `X | Y` for type annotations
4544
]
4645

46+
# TODO: fix these checks separately
47+
# "E501" - Line too long
48+
# "F401" - Unused imports
49+
4750
[tool.ruff.lint.per-file-ignores]
4851
"__init__.py" = [
4952
"F401" # unused-import

tests/test_handlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_delete_plugin(self):
9393

9494
with self.login_user_context(self.get_superuser()):
9595
response = self.client.post(endpoint, data)
96-
self.assertEqual(response.status_code, 302)
96+
self.assertIn(response.status_code, (200, 302)) # 302 for django CMS < 5
9797

9898
version = Version.objects.get(pk=version.pk)
9999
self.assertEqual(version.modified, dt)

tests/test_integration_with_core.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
from cms.toolbar.toolbar import CMSToolbar
66
from cms.utils.urlutils import admin_reverse
77
from django.template import Context
8+
from packaging.version import Version as PackageVersion
89

910
from djangocms_versioning import constants
10-
from djangocms_versioning.plugin_rendering import VersionContentRenderer
11+
from djangocms_versioning.plugin_rendering import CMSToolbarVersioningMixin, VersionContentRenderer
1112
from djangocms_versioning.test_utils.factories import (
1213
PageFactory,
1314
PageVersionFactory,
@@ -18,12 +19,14 @@
1819
)
1920

2021

22+
@skipIf(PackageVersion(cms_version) >= PackageVersion("4.2"), "Toolbar integration not necessary for django CMS 4.2+")
2123
class CMSToolbarTestCase(CMSTestCase):
2224
def test_content_renderer(self):
2325
"""Test that cms.toolbar.toolbar.CMSToolbar.content_renderer
2426
is replaced with a property returning VersionContentRenderer
2527
"""
2628
request = self.get_request("/")
29+
self.assertIn(CMSToolbarVersioningMixin, CMSToolbar.__mro__)
2730
self.assertEqual(
2831
CMSToolbar(request).content_renderer.__class__, VersionContentRenderer
2932
)
@@ -38,7 +41,6 @@ def test_cmstoolbar_mixin(self):
3841

3942

4043
class PageContentAdminTestCase(CMSTestCase):
41-
4244
def test_get_admin_model_object(self):
4345
"""
4446
PageContent normally won't be able to fetch objects in draft. Test if the RequestToolbarForm
@@ -70,7 +72,6 @@ def test_get_title_cache(self):
7072

7173

7274
class PageAdminCopyLanguageTestCase(CMSTestCase):
73-
7475
def setUp(self):
7576
self.user = self.get_superuser()
7677
page = PageFactory()
@@ -276,11 +277,16 @@ def setUp(self):
276277
content__language="fr",
277278
state=constants.ARCHIVED,
278279
)
279-
self.page.languages = "en,fr"
280+
try:
281+
self.page.languages = "en,fr"
282+
except AttributeError:
283+
# The property does not have a setter in django CMS 5+
284+
pass
280285
self.page.save()
281286

282287

283-
@skipIf(cms_version < "4.1.4", "Bug only fixed in django CMS 4.1.4")
288+
@skipIf(PackageVersion(cms_version) < PackageVersion("4.1.4"),
289+
"Bug only fixed in django CMS 4.1.4")
284290
def test_get_admin_url_for_language(self):
285291
"""Regression fixed that made unpublished and archived versions invisible to get_admin_url_for_language
286292
template tag. See: https://github.com/django-cms/django-cms/pull/7967"""

0 commit comments

Comments
 (0)