From 62ce7028af8ba3ebab2ecf347ca54fab2e6641b4 Mon Sep 17 00:00:00 2001 From: Filip Weidemann Date: Tue, 29 Oct 2024 08:44:24 +0100 Subject: [PATCH 1/4] fix: setting partial admin_content_cache was responsible for rendering create forms inside the admin language tabs --- cms/admin/pageadmin.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py index ab590247cee..80b0a630923 100644 --- a/cms/admin/pageadmin.py +++ b/cms/admin/pageadmin.py @@ -740,11 +740,7 @@ def get_object(self, request, object_id, from_field=None): key is used if no field is provided. Return ``None`` if no match is found or the object_id fails validation. """ - obj = super().get_object(request, object_id, from_field) - - if obj: - obj.page.admin_content_cache[obj.language] = obj - return obj + return super().get_object(request, object_id, from_field) def get_admin_url(self, action, *args): url_name = f"{self.opts.app_label}_{self.opts.model_name}_{action}" From 62e65809b997effb058282215492acf48f273369 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 29 Oct 2024 09:43:42 +0100 Subject: [PATCH 2/4] Update pagemodel.py to also include latest versions in language tabs if they are unpublished or archived --- cms/models/pagemodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/models/pagemodel.py b/cms/models/pagemodel.py index 12428b7d93e..d63337e818e 100644 --- a/cms/models/pagemodel.py +++ b/cms/models/pagemodel.py @@ -722,7 +722,7 @@ def set_translations_cache(self): self.page_content_cache.setdefault(translation.language, translation) def set_admin_content_cache(self): - for translation in self.pagecontent_set(manager="admin_manager").current_content().all(): + for translation in self.pagecontent_set(manager="admin_manager").latest_content().all(): self.admin_content_cache.setdefault(translation.language, translation) def get_admin_content(self, language, fallback=False): From 1ec8b216348ee3e7dfe98da141fdf80b6dc54393 Mon Sep 17 00:00:00 2001 From: Filip Weidemann Date: Tue, 29 Oct 2024 10:10:59 +0100 Subject: [PATCH 3/4] fix: remove get_object on PageContentAdmin --- cms/admin/pageadmin.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py index 80b0a630923..d7460bf5526 100644 --- a/cms/admin/pageadmin.py +++ b/cms/admin/pageadmin.py @@ -734,14 +734,6 @@ def log_change(self, request, object, message): # Block the admin log for change. A signal takes care of this! return - def get_object(self, request, object_id, from_field=None): - """ - Return an instance matching the field and value provided, the primary - key is used if no field is provided. Return ``None`` if no match is - found or the object_id fails validation. - """ - return super().get_object(request, object_id, from_field) - def get_admin_url(self, action, *args): url_name = f"{self.opts.app_label}_{self.opts.model_name}_{action}" return admin_reverse(url_name, args=args) From 0ed79dd0adae0c1ed6a91a0ebbd5865b938261f5 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 29 Oct 2024 17:06:11 +0100 Subject: [PATCH 4/4] chore: Introduce AdminCacheDict --- cms/models/pagemodel.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cms/models/pagemodel.py b/cms/models/pagemodel.py index d63337e818e..c0a0316a7ca 100644 --- a/cms/models/pagemodel.py +++ b/cms/models/pagemodel.py @@ -28,6 +28,12 @@ logger = getLogger(__name__) +class AdminCacheDict(dict): + """Dictionary that disallows setting individual items to prevent accidental cache corruption.""" + def __setitem__(self, key, value): + raise ValueError("Do not set individual items in the admin cache dict. Use the clear_cache method instead.") + + class Page(MP_Node): """ A ``Page`` is the basic unit of site structure in django CMS. The CMS uses a hierarchical page model: each page @@ -139,7 +145,7 @@ def __init__(self, *args, **kwargs): self.urls_cache = {} self.page_content_cache = {} #: Internal cache for page content objects visible publicly - self.admin_content_cache = {} + self.admin_content_cache = AdminCacheDict() #: Internal cache for page content objects visible in the admin (i.e. to staff users.) #: Might be larger than the page_content_cache @@ -203,7 +209,7 @@ def get_cached_descendants(self): def _clear_internal_cache(self): self.urls_cache = {} self.page_content_cache = {} - self.admin_content_cache = {} + self.admin_content_cache = AdminCacheDict() if hasattr(self, '_prefetched_objects_cache'): del self._prefetched_objects_cache @@ -722,6 +728,7 @@ def set_translations_cache(self): self.page_content_cache.setdefault(translation.language, translation) def set_admin_content_cache(self): + self.admin_conent_cache = AdminCacheDict() for translation in self.pagecontent_set(manager="admin_manager").latest_content().all(): self.admin_content_cache.setdefault(translation.language, translation)