From 233790aaeef735f3d6472756e95231a015fba0b3 Mon Sep 17 00:00:00 2001 From: Jens-Erik Weber Date: Wed, 30 Oct 2024 21:09:43 +0100 Subject: [PATCH 1/3] style: ruff format cms/admin/pageadmin.py --- cms/admin/pageadmin.py | 545 ++++++++++++++++++++--------------------- 1 file changed, 269 insertions(+), 276 deletions(-) diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py index d7460bf5526..ba627c89dd4 100644 --- a/cms/admin/pageadmin.py +++ b/cms/admin/pageadmin.py @@ -84,7 +84,7 @@ def get_site(request): - site_id = request.session.get('cms_admin_site') + site_id = request.session.get("cms_admin_site") if not site_id: return get_current_site() @@ -98,7 +98,7 @@ def get_site(request): @admin.register(Page) class PageAdmin(admin.ModelAdmin): - actions_menu_template = 'admin/cms/page/tree/actions_dropdown.html' + actions_menu_template = "admin/cms/page/tree/actions_dropdown.html" form = AdvancedSettingsForm copy_form = CopyPageForm @@ -147,7 +147,7 @@ def get_preserved_filters(self, request): lang = get_site_language_from_request(request, site_id=site.pk) if lang: - preserved_filters['language'] = lang + preserved_filters["language"] = lang return preserved_filters.urlencode() def get_queryset(self, request): @@ -166,22 +166,22 @@ def get_page_from_id(self, page_id): return page def get_urls(self): - """Get the admin urls - """ + """Get the admin urls""" info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" + def pat(regex, fn): - return re_path(regex, self.admin_site.admin_view(fn), name=f'{info}_{fn.__name__}') + return re_path(regex, self.admin_site.admin_view(fn), name=f"{info}_{fn.__name__}") url_patterns = [ - pat(r'^list/$', self.get_list), - pat(r'^([0-9]+)/actions-menu/$', self.actions_menu), - pat(r'^([0-9]+)/([a-z\-]+)/edit-field/$', self.edit_title_fields), - pat(r'^([0-9]+)/advanced-settings/$', self.advanced), - pat(r'^([0-9]+)/move-page/$', self.move_page), - pat(r'^([0-9]+)/copy-page/$', self.copy_page), - pat(r'^([0-9]+)/dialog/copy/$', self.get_copy_dialog), # copy dialog - pat(r'^([0-9]+)/permissions/$', self.get_permissions), - pat(r'^([0-9]+)/set-home/$', self.set_home), + pat(r"^list/$", self.get_list), + pat(r"^([0-9]+)/actions-menu/$", self.actions_menu), + pat(r"^([0-9]+)/([a-z\-]+)/edit-field/$", self.edit_title_fields), + pat(r"^([0-9]+)/advanced-settings/$", self.advanced), + pat(r"^([0-9]+)/move-page/$", self.move_page), + pat(r"^([0-9]+)/copy-page/$", self.copy_page), + pat(r"^([0-9]+)/dialog/copy/$", self.get_copy_dialog), # copy dialog + pat(r"^([0-9]+)/permissions/$", self.get_permissions), + pat(r"^([0-9]+)/set-home/$", self.set_home), ] if plugin_pool.registered_plugins: @@ -189,7 +189,7 @@ def pat(regex, fn): return url_patterns + super().get_urls() def get_inline_instances(self, request, obj=None): - if obj and get_cms_setting('PERMISSION'): + if obj and get_cms_setting("PERMISSION"): can_change_perms = self.has_change_permissions_permission(request, obj=obj) else: can_change_perms = False @@ -215,21 +215,21 @@ def actions_menu(self, request, object_id, extra_context=None): raise self._get_404_exception(object_id) site = get_site(request) - paste_enabled = request.GET.get('has_copy') or request.GET.get('has_cut') + paste_enabled = request.GET.get("has_copy") or request.GET.get("has_cut") context = { - 'page': page, - 'opts': self.opts, - 'site': site, - 'page_is_restricted': page.has_view_restrictions(site), - 'paste_enabled': paste_enabled, - 'has_add_permission': page_permissions.user_can_add_subpage(request.user, target=page), - 'has_copy_page_permission': page_permissions.user_can_view_page_draft(request.user, page, site=site), - 'has_change_permission': self.has_change_permission(request, obj=page), - 'has_change_advanced_settings_permission': self.has_change_advanced_settings_permission(request, obj=page), - 'has_change_permissions_permission': self.has_change_permissions_permission(request, obj=page), - 'has_move_page_permission': self.has_move_page_permission(request, obj=page), - 'has_delete_permission': self.has_delete_permission(request, obj=page), - 'CMS_PERMISSION': get_cms_setting('PERMISSION'), + "page": page, + "opts": self.opts, + "site": site, + "page_is_restricted": page.has_view_restrictions(site), + "paste_enabled": paste_enabled, + "has_add_permission": page_permissions.user_can_add_subpage(request.user, target=page), + "has_copy_page_permission": page_permissions.user_can_view_page_draft(request.user, page, site=site), + "has_change_permission": self.has_change_permission(request, obj=page), + "has_change_advanced_settings_permission": self.has_change_advanced_settings_permission(request, obj=page), + "has_change_permissions_permission": self.has_change_permissions_permission(request, obj=page), + "has_move_page_permission": self.has_move_page_permission(request, obj=page), + "has_delete_permission": self.has_delete_permission(request, obj=page), + "CMS_PERMISSION": get_cms_setting("PERMISSION"), } if extra_context: @@ -245,11 +245,11 @@ def advanced(self, request, object_id): if page is None: raise self._get_404_exception(object_id) - if get_cms_setting('PERMISSION'): + if get_cms_setting("PERMISSION"): show_permissions = self.has_change_permissions_permission(request, obj=page) else: show_permissions = False - context = {'title': _("Advanced Settings"), 'show_permissions': show_permissions} + context = {"title": _("Advanced Settings"), "show_permissions": show_permissions} return self.change_view(request, object_id, extra_context=context) def response_post_save_change(self, request, obj): @@ -265,9 +265,9 @@ def response_post_save_change(self, request, obj): if can_change_any_page: query = self.get_preserved_filters(request) - post_url = admin_reverse('cms_pagecontent_changelist') + '?' + query + post_url = admin_reverse("cms_pagecontent_changelist") + "?" + query else: - post_url = admin_reverse('index') + post_url = admin_reverse("index") return HttpResponseRedirect(post_url) @require_POST @@ -300,45 +300,40 @@ def set_home(self, request, object_id): # One or more pages affected by this operation was attached to an apphook. # As a result, fire the apphook reload signal to reload the url patterns. set_restart_trigger() - return HttpResponse('ok') + return HttpResponse("ok") def get_list(self, *args, **kwargs): """ - This view is used by the PageSmartLinkWidget as the user type to feed the autocomplete drop-down. + This view is used by the PageSmartLinkWidget as the user type to feed the autocomplete drop-down. """ request = args[0] - if request.headers.get('x-requested-with') == 'XMLHttpRequest': - query_term = request.GET.get('q', '').strip('/') + if request.headers.get("x-requested-with") == "XMLHttpRequest": + query_term = request.GET.get("q", "").strip("/") - language_code = request.GET.get('language_code', settings.LANGUAGE_CODE) + language_code = request.GET.get("language_code", settings.LANGUAGE_CODE) matching_published_pages = self.model.objects.filter( - Q( - pagecontent_set__title__icontains=query_term, pagecontent_set__language=language_code - ) | Q( - urls__path__icontains=query_term, pagecontent_set__language=language_code - ) | Q( - pagecontent_set__menu_title__icontains=query_term, pagecontent_set__language=language_code - ) | Q( - pagecontent_set__page_title__icontains=query_term, pagecontent_set__language=language_code - ) + Q(pagecontent_set__title__icontains=query_term, pagecontent_set__language=language_code) + | Q(urls__path__icontains=query_term, pagecontent_set__language=language_code) + | Q(pagecontent_set__menu_title__icontains=query_term, pagecontent_set__language=language_code) + | Q(pagecontent_set__page_title__icontains=query_term, pagecontent_set__language=language_code) ).distinct() results = [] for page in matching_published_pages: results.append( { - 'path': page.get_path(language=language_code), - 'title': page.get_title(language=language_code), - 'redirect_url': page.get_absolute_url(language=language_code) + "path": page.get_path(language=language_code), + "title": page.get_title(language=language_code), + "redirect_url": page.get_absolute_url(language=language_code), } ) - return HttpResponse(json.dumps(results), content_type='application/json') + return HttpResponse(json.dumps(results), content_type="application/json") return HttpResponseForbidden() def changelist_view(self, request, extra_context=None): parameter = "?" + request.GET.urlencode() if request.GET else "" - return HttpResponseRedirect(admin_reverse('cms_pagecontent_changelist') + parameter) + return HttpResponseRedirect(admin_reverse("cms_pagecontent_changelist") + parameter) def response_delete(self, request, obj_display, obj_id): """ @@ -356,21 +351,18 @@ def get_deleted_objects(self, objs, request): def delete_model(self, request, obj): operation_token = send_pre_page_operation( - request=request, - operation=operations.DELETE_PAGE, - obj=obj, - sender=self.model + request=request, operation=operations.DELETE_PAGE, obj=obj, sender=self.model ) cms_pages = [obj] if obj.is_branch: - descendant_ids = obj.get_descendants().values_list('id', flat=True) + descendant_ids = obj.get_descendants().values_list("id", flat=True) cms_pages.extend(self.model.objects.filter(id__in=descendant_ids)) # Delete all associated pages contents ct_page_content = ContentType.objects.get_for_model(PageContent) - page_content_objs = PageContent.admin_manager.filter(page__in=cms_pages).values_list('pk', flat=True) + page_content_objs = PageContent.admin_manager.filter(page__in=cms_pages).values_list("pk", flat=True) placeholders = Placeholder.objects.filter( content_type=ct_page_content, object_id__in=page_content_objs, @@ -395,26 +387,26 @@ def delete_model(self, request, obj): set_restart_trigger() def get_copy_dialog(self, request, page_id): - if not get_cms_setting('PERMISSION'): - return HttpResponse('') + if not get_cms_setting("PERMISSION"): + return HttpResponse("") page = self.get_page_from_id(page_id) if page is None: raise self._get_404_exception(page_id) - if request.method == 'GET': + if request.method == "GET": data = request.GET else: data = request.POST - target_id = data.get('target') + target_id = data.get("target") try: - source_site_id = data['source_site'] + source_site_id = data["source_site"] source_site = Site.objects.get(pk=source_site_id) except (KeyError, ObjectDoesNotExist): - return HttpResponseBadRequest('source_site is required') + return HttpResponseBadRequest("source_site is required") site = get_site(request) user = request.user @@ -435,17 +427,20 @@ def get_copy_dialog(self, request, page_id): raise PermissionDenied context = { - 'dialog_id': 'dialog-copy', - 'form': CopyPermissionForm(), # class needs to be instantiated - 'opts': self.opts, + "dialog_id": "dialog-copy", + "form": CopyPermissionForm(), # class needs to be instantiated + "opts": self.opts, } return render(request, "admin/cms/page/tree/copy_premissions.html", context) def _get_404_exception(self, object_id): - exception = Http404(_('%(name)s object with primary key %(key)r does not exist.') % { - 'name': force_str(self.opts.verbose_name), - 'key': escape(object_id), - }) + exception = Http404( + _("%(name)s object with primary key %(key)r does not exist.") + % { + "name": force_str(self.opts.verbose_name), + "key": escape(object_id), + } + ) return exception def has_view_permission(self, request, obj=None): @@ -507,14 +502,12 @@ def move_page(self, request, page_id, extra_context=None): if not form.is_valid(): return jsonify_request(HttpResponseBadRequest("error")) - target = form.cleaned_data['target'] + target = form.cleaned_data["target"] can_move_page = self.has_move_page_permission(request, obj=page) # Does the user have permissions to do this...? if not can_move_page or (target and not target.has_add_permission(user)): - message = _( - "Error! You don't have permissions to move this page. Please reload the page" - ) + message = _("Error! You don't have permissions to move this page. Please reload the page") return jsonify_request(HttpResponseForbidden(message)) operation_token = send_pre_page_operation( @@ -544,7 +537,7 @@ def get_permissions(self, request, page_id): raise self._get_404_exception(page_id) site = get_site(request) - PermissionRow = namedtuple('Permission', ['is_global', 'can_change', 'permission']) + PermissionRow = namedtuple("Permission", ["is_global", "can_change", "permission"]) global_permissions = GlobalPagePermission.objects.filter(sites__in=[site.pk]) can_change_global_permissions = permissions.user_can_change_global_permissions(user, site) @@ -557,12 +550,7 @@ def get_permissions(self, request, page_id): ) rows.append(row) - _page_permissions = ( - PagePermission - .objects - .for_page(page) - .select_related('page') - ) + _page_permissions = PagePermission.objects.for_page(page).select_related("page") if not can_change_global_permissions: allowed_pages = page_permissions.get_change_perm_tuples(user, site, check_global=False) @@ -582,11 +570,11 @@ def get_permissions(self, request, page_id): rows.append(row) context = { - 'page': page, - 'rows': rows, - 'opts': self.opts, + "page": page, + "rows": rows, + "opts": self.opts, } - return render(request, 'admin/cms/page/permissions.html', context) + return render(request, "admin/cms/page/permissions.html", context) @require_POST @transaction.atomic @@ -607,8 +595,8 @@ def copy_page(self, request, page_id): if not form.is_valid(): return jsonify_request(HttpResponseBadRequest("error")) - target = form.cleaned_data['target'] - source_site = form.cleaned_data['source_site'] + target = form.cleaned_data["target"] + source_site = form.cleaned_data["source_site"] # User can only copy pages he can see can_copy_page = page_permissions.user_can_view_page(user, page, source_site) @@ -636,7 +624,7 @@ def copy_page(self, request, page_id): return jsonify_request(HttpResponseBadRequest(message)) new_page = form.copy_page(user) - return HttpResponse(json.dumps({"id": new_page.pk}), content_type='application/json') + return HttpResponse(json.dumps({"id": new_page.pk}), content_type="application/json") def edit_title_fields(self, request, page_id, language): page = self.get_object(request, object_id=page_id) @@ -649,70 +637,74 @@ def edit_title_fields(self, request, page_id, language): raise self._get_404_exception(page_id) if not translation: - raise Http404('No translation matches requested language.') + raise Http404("No translation matches requested language.") saved_successfully = False - raw_fields = request.GET.get("edit_fields", 'title') + raw_fields = request.GET.get("edit_fields", "title") edit_fields = [field for field in raw_fields.split(",") if field in self.title_frontend_editable_fields] cancel_clicked = request.POST.get("_cancel", False) opts = PageContent._meta if not edit_fields: # Defaults to title - edit_fields = ('title',) + edit_fields = ("title",) class PageTitleForm(django.forms.ModelForm): """ Dynamic form showing only the fields to be edited """ + class Meta: model = PageContent fields = edit_fields - if not cancel_clicked and request.method == 'POST': + if not cancel_clicked and request.method == "POST": form = PageTitleForm(instance=translation, data=request.POST) if form.is_valid(): form.save() saved_successfully = True else: form = PageTitleForm(instance=translation) - admin_form = AdminForm(form, fieldsets=[(None, {'fields': edit_fields})], prepopulated_fields={}, - model_admin=self) + admin_form = AdminForm( + form, fieldsets=[(None, {"fields": edit_fields})], prepopulated_fields={}, model_admin=self + ) media = self.media + admin_form.media context = { - 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), - 'title': 'Title', - 'plugin': page, - 'plugin_id': page.pk, - 'adminform': admin_form, - 'add': False, - 'is_popup': True, - 'media': media, - 'opts': opts, - 'change': True, - 'save_as': False, - 'has_add_permission': False, - 'window_close_timeout': 10, + "CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), + "title": "Title", + "plugin": page, + "plugin_id": page.pk, + "adminform": admin_form, + "add": False, + "is_popup": True, + "media": media, + "opts": opts, + "change": True, + "save_as": False, + "has_add_permission": False, + "window_close_timeout": 10, } if cancel_clicked: # cancel button was clicked - context.update({ - 'cancel': True, - }) - return render(request, 'admin/cms/page/plugin/confirm_form.html', context) - if not cancel_clicked and request.method == 'POST' and saved_successfully: - return render(request, 'admin/cms/page/plugin/confirm_form.html', context) - return render(request, 'admin/cms/page/plugin/change_form.html', context) + context.update( + { + "cancel": True, + } + ) + return render(request, "admin/cms/page/plugin/confirm_form.html", context) + if not cancel_clicked and request.method == "POST" and saved_successfully: + return render(request, "admin/cms/page/plugin/confirm_form.html", context) + return render(request, "admin/cms/page/plugin/change_form.html", context) @admin.register(PageContent) class PageContentAdmin(admin.ModelAdmin): - ordering = ('page__path',) - search_fields = ('=id', 'page__id', 'page__urls__slug', 'title', 'page__reverse_id') + ordering = ("page__path",) + search_fields = ("=id", "page__id", "page__urls__slug", "title", "page__reverse_id") change_form_template = "admin/cms/page/change_form.html" change_list_template = "admin/cms/page/tree/base.html" - actions_menu_template = 'admin/cms/page/tree/actions_dropdown.html' - page_tree_row_template = 'admin/cms/page/tree/menu.html' + actions_menu_template = "admin/cms/page/tree/actions_dropdown.html" + page_tree_row_template = "admin/cms/page/tree/menu.html" form = AddPageForm add_form = form @@ -749,29 +741,29 @@ def get_preserved_filters(self, request): lang = get_site_language_from_request(request, site_id=site.pk) if lang: - preserved_filters['language'] = lang + preserved_filters["language"] = lang return preserved_filters.urlencode() def get_queryset(self, request): site = get_site(request) languages = get_language_list(site.pk) - queryset = super().get_queryset(request).select_related('page') + queryset = super().get_queryset(request).select_related("page") queryset = queryset.filter(language__in=languages, page__site=site) return queryset def get_urls(self): - """Get the admin urls - """ + """Get the admin urls""" info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" + def pat(regex, fn): - return re_path(regex, self.admin_site.admin_view(fn), name=f'{info}_{fn.__name__}') + return re_path(regex, self.admin_site.admin_view(fn), name=f"{info}_{fn.__name__}") url_patterns = [ - pat(r'^get-tree/$', self.get_tree), - pat(r'^([0-9]+)/duplicate/$', self.duplicate), - pat(r'^([0-9]+)/copy-language/$', self.copy_language), - pat(r'^([0-9]+)/change-navigation/$', self.change_innavigation), - pat(r'^([0-9]+)/change-template/$', self.change_template), + pat(r"^get-tree/$", self.get_tree), + pat(r"^([0-9]+)/duplicate/$", self.duplicate), + pat(r"^([0-9]+)/copy-language/$", self.copy_language), + pat(r"^([0-9]+)/change-navigation/$", self.change_innavigation), + pat(r"^([0-9]+)/change-template/$", self.change_template), ] return url_patterns + super().get_urls() @@ -782,13 +774,13 @@ def get_fieldsets(self, request, obj=None): fieldsets = form.fieldsets except AttributeError: fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) - fieldsets = [(None, {'fields': fields})] + fieldsets = [(None, {"fields": fields})] return fieldsets def get_form_class(self, request, obj=None, **kwargs): - if 'change' in request.path_info: + if "change" in request.path_info: return self.change_form - elif 'duplicate' in request.path_info: + elif "duplicate" in request.path_info: return self.duplicate_form return self.add_form @@ -797,12 +789,7 @@ def get_form(self, request, obj=None, **kwargs): Get PageForm for the Page model and modify its fields depending on the request. """ - form = super().get_form( - request, - obj, - form=self.get_form_class(request, obj), - **kwargs - ) + form = super().get_form(request, obj, form=self.get_form_class(request, obj), **kwargs) form._site = get_site(request) form._request = request return form @@ -830,55 +817,61 @@ def duplicate(self, request, object_id): if obj is None: raise self._get_404_exception(object_id) - if request.method == 'GET': + if request.method == "GET": # source is a field in the form # because its value is in the url, # we have to set the initial value manually request.GET = request.GET.copy() - request.GET['source'] = obj.page_id + request.GET["source"] = obj.page_id return self.add_view(request) - def add_view(self, request, form_url='', extra_context=None): + def add_view(self, request, form_url="", extra_context=None): site = get_site(request) language = get_site_language_from_request(request, site_id=site.pk) if extra_context is None: extra_context = {} - if 'duplicate' in request.path_info: - extra_context.update({ - 'title': _("Add Page Copy"), - }) - elif 'parent_page' in request.GET: - extra_context.update({ - 'title': _("New sub page"), - }) + if "duplicate" in request.path_info: + extra_context.update( + { + "title": _("Add Page Copy"), + } + ) + elif "parent_page" in request.GET: + extra_context.update( + { + "title": _("New sub page"), + } + ) else: - extra_context.update({ - 'title': _("New page"), - }) + extra_context.update( + { + "title": _("New page"), + } + ) try: - page_id = request.GET.get('cms_page') or request.POST.get('cms_page') + page_id = request.GET.get("cms_page") or request.POST.get("cms_page") page_id = IntegerField().clean(page_id) cms_page = Page.objects.get(pk=page_id) except (ValidationError, Page.DoesNotExist): cms_page = None if cms_page: - extra_context['cms_page'] = cms_page - extra_context['language_tabs'] = get_language_tuple(site.pk) - extra_context['filled_languages'] = self.get_filled_languages(request, cms_page) - extra_context['show_language_tabs'] = len(extra_context['language_tabs']) - extra_context['language'] = language + extra_context["cms_page"] = cms_page + extra_context["language_tabs"] = get_language_tuple(site.pk) + extra_context["filled_languages"] = self.get_filled_languages(request, cms_page) + extra_context["show_language_tabs"] = len(extra_context["language_tabs"]) + extra_context["language"] = language return super().add_view(request, form_url, extra_context=extra_context) - def change_view(self, request, object_id, form_url='', extra_context=None): + def change_view(self, request, object_id, form_url="", extra_context=None): """ The 'change' admin view for the PageContent model. """ if extra_context is None: - extra_context = {'basic_info': True} + extra_context = {"basic_info": True} obj = self.get_object(request, object_id=object_id) @@ -887,19 +880,19 @@ def change_view(self, request, object_id, form_url='', extra_context=None): site = get_site(request) context = { - 'cms_page': obj.page, - 'CMS_PERMISSION': get_cms_setting('PERMISSION'), - 'can_change': self.has_change_permission(request, obj=obj), - 'language': obj.language, - 'language_tabs': get_language_tuple(site.pk), - 'filled_languages': self.get_filled_languages(request, obj.page) + "cms_page": obj.page, + "CMS_PERMISSION": get_cms_setting("PERMISSION"), + "can_change": self.has_change_permission(request, obj=obj), + "language": obj.language, + "language_tabs": get_language_tuple(site.pk), + "filled_languages": self.get_filled_languages(request, obj.page), } - context['show_language_tabs'] = len(context['language_tabs']) + context["show_language_tabs"] = len(context["language_tabs"]) context.update(extra_context or {}) - if 'basic_info' in extra_context: + if "basic_info" in extra_context: _has_advanced_settings_perm = self.has_change_advanced_settings_permission(request, obj=obj) - context['can_change_advanced_settings'] = _has_advanced_settings_perm + context["can_change_advanced_settings"] = _has_advanced_settings_perm return super().change_view(request, object_id, form_url=form_url, extra_context=context) @@ -909,14 +902,14 @@ def response_add(self, request, obj): from django.core.cache import cache from cms.cache.permissions import get_cache_key, get_cache_permission_version - cache.delete(get_cache_key(request.user, 'change_page'), version=get_cache_permission_version()) + + cache.delete(get_cache_key(request.user, "change_page"), version=get_cache_permission_version()) # redirect to the edit view if added from the toolbar url = get_object_edit_url(obj) # Redirects to preview if necessary return HttpResponse(MODAL_HTML_REDIRECT.format(url=url)) return super().response_add(request, obj) - def get_filled_languages(self, request, page): site_id = get_site(request).pk filled_languages = page.get_languages() @@ -924,15 +917,18 @@ def get_filled_languages(self, request, page): return [lang for lang in filled_languages if lang in allowed_languages] def _get_404_exception(self, object_id): - exception = Http404(_('%(name)s object with primary key %(key)r does not exist.') % { - 'name': force_str(self.opts.verbose_name), - 'key': escape(object_id), - }) + exception = Http404( + _("%(name)s object with primary key %(key)r does not exist.") + % { + "name": force_str(self.opts.verbose_name), + "key": escape(object_id), + } + ) return exception def _has_add_permission_from_request(self, request): site = get_site(request) - if parent_id := request.GET.get('parent_page'): + if parent_id := request.GET.get("parent_page"): try: parent_id = IntegerField().clean(parent_id) parent_item = Page.objects.get(id=parent_id) @@ -1024,15 +1020,15 @@ def changelist_view(self, request, extra_context=None): if not self.has_change_permission(request, obj=None): raise PermissionDenied - if request.method == 'POST' and 'site' in request.POST: - site_id = request.POST['site'] + if request.method == "POST" and "site" in request.POST: + site_id = request.POST["site"] if site_id.isdigit() and Site.objects.filter(pk=site_id).exists(): - request.session['cms_admin_site'] = site_id + request.session["cms_admin_site"] = site_id site = get_site(request) language = get_site_language_from_request(request, site_id=site.pk) - query = request.GET.get('q', '') + query = request.GET.get("q", "") page_contents = self.get_queryset(request) page_contents, _ = self.get_search_results(request, page_contents, query) changelist_form = self.changelist_form(request.GET) @@ -1048,23 +1044,19 @@ def changelist_view(self, request, extra_context=None): # something is screwed up with the database, so display an error # page. if ERROR_FLAG in request.GET.keys(): - return SimpleTemplateResponse('admin/invalid_setup.html', { - 'title': _('Database error'), - }) - return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1') - - pages = ( - Page - .objects - .on_site(site) - .filter(pagecontent_set__in=page_contents) - .distinct() - .order_by('path') - ) + return SimpleTemplateResponse( + "admin/invalid_setup.html", + { + "title": _("Database error"), + }, + ) + return HttpResponseRedirect(request.path + "?" + ERROR_FLAG + "=1") + + pages = Page.objects.on_site(site).filter(pagecontent_set__in=page_contents).distinct().order_by("path") pages = pages.prefetch_related( Prefetch( - 'pagecontent_set', - to_attr='filtered_translations', + "pagecontent_set", + to_attr="filtered_translations", queryset=page_contents, ), ) @@ -1076,26 +1068,28 @@ def changelist_view(self, request, extra_context=None): has_items = pages.exists() context = self.admin_site.each_context(request) - context.update({ - 'opts': self.model._meta, - 'media': self.media, - 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), - 'CMS_PERMISSION': get_cms_setting('PERMISSION'), - 'site_languages': get_language_tuple(site.pk), - 'preview_language': language, - 'changelist_form': changelist_form, - 'cms_current_site': site, - 'has_add_permission': self.has_add_permission(request), - 'module_name': force_str(self.model._meta.verbose_name_plural), - 'admin': self, - 'tree': { - 'site': site, - 'query': query, - 'is_filtered': changelist_form.is_filtered(), - 'items': pages, - 'has_items': has_items, - }, - }) + context.update( + { + "opts": self.model._meta, + "media": self.media, + "CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), + "CMS_PERMISSION": get_cms_setting("PERMISSION"), + "site_languages": get_language_tuple(site.pk), + "preview_language": language, + "changelist_form": changelist_form, + "cms_current_site": site, + "has_add_permission": self.has_add_permission(request), + "module_name": force_str(self.model._meta.verbose_name_plural), + "admin": self, + "tree": { + "site": site, + "query": query, + "is_filtered": changelist_form.is_filtered(), + "items": pages, + "has_items": has_items, + }, + } + ) context.update(extra_context or {}) request.current_app = self.admin_site.name return TemplateResponse(request, self.change_list_template, context) @@ -1105,24 +1099,23 @@ def change_template(self, request, object_id): page_content = self.get_object(request, object_id=object_id) if not self.has_change_permission(request, obj=page_content): - raise PermissionDenied('No permissions to change the template') + raise PermissionDenied("No permissions to change the template") if page_content is None: raise self._get_404_exception(object_id) if not self.has_change_advanced_settings_permission(request, obj=page_content): - raise PermissionDenied('No permissions to change the template') + raise PermissionDenied("No permissions to change the template") to_template = request.POST.get("template", None) - if get_cms_setting('TEMPLATES'): - if to_template not in dict(get_cms_setting('TEMPLATES')): + if get_cms_setting("TEMPLATES"): + if to_template not in dict(get_cms_setting("TEMPLATES")): return HttpResponseBadRequest(_("Template not valid")) else: - if to_template not in (placeholder_set[0] for placeholder_set in get_cms_setting('PLACEHOLDERS')): + if to_template not in (placeholder_set[0] for placeholder_set in get_cms_setting("PLACEHOLDERS")): return HttpResponseBadRequest(_("Placeholder selection not valid")) - page_content.template = to_template page_content.save() @@ -1131,7 +1124,7 @@ def change_template(self, request, object_id): @require_POST @transaction.atomic def copy_language(self, request, object_id): - target_language = request.POST.get('target_language') + target_language = request.POST.get("target_language") source_page_content = self.get_object(request, object_id=object_id) if not self.has_change_permission(request, obj=source_page_content): @@ -1172,7 +1165,7 @@ def delete_view(self, request, object_id, extra_context=None): raise self._get_404_exception(object_id) if not len(list(page.get_languages())) > 1: - return HttpResponseBadRequest('There only exists one translation for this page') + return HttpResponseBadRequest("There only exists one translation for this page") titleopts = PageContent._meta app_label = titleopts.app_label @@ -1198,11 +1191,9 @@ def delete_view(self, request, object_id, extra_context=None): )[:3] to_delete_objects = [to_delete_urls, to_delete_plugins, to_delete_translations] - perms_needed = set( - list(perms_needed_url) + list(perms_needed_translation) + list(perms_needed_plugins) - ) + perms_needed = set(list(perms_needed_url) + list(perms_needed_translation) + list(perms_needed_plugins)) - if request.method == 'POST': + if request.method == "POST": if perms_needed: raise PermissionDenied @@ -1211,11 +1202,11 @@ def delete_view(self, request, object_id, extra_context=None): operation=operations.DELETE_PAGE_TRANSLATION, obj=page, translation=page_content, - sender=self.model + sender=self.model, ) - message = _('Title and plugins with language %(language)s was deleted') % { - 'language': force_str(get_language_object(language)['name']) + message = _("Title and plugins with language %(language)s was deleted") % { + "language": force_str(get_language_object(language)["name"]) } messages.success(request, message) @@ -1236,10 +1227,10 @@ def delete_view(self, request, object_id, extra_context=None): ) if not self.has_change_permission(request, None): - return HttpResponseRedirect(admin_reverse('index')) + return HttpResponseRedirect(admin_reverse("index")) - redirect_to = self.get_admin_url('changelist') - redirect_to += f'?language={request_language}' + redirect_to = self.get_admin_url("changelist") + redirect_to += f"?language={request_language}" return HttpResponseRedirect(redirect_to) context = { @@ -1249,16 +1240,21 @@ def delete_view(self, request, object_id, extra_context=None): "deleted_objects": to_delete_objects, "perms_lacking": perms_needed, "opts": self.opts, - "root_path": admin_reverse('index'), + "root_path": admin_reverse("index"), "app_label": app_label, } context.update(extra_context or {}) request.current_app = self.admin_site.name - return render(request, self.delete_confirmation_template or [ - f"admin/{app_label}/{titleopts.object_name.lower()}/delete_confirmation.html", - "admin/%s/delete_confirmation.html" % app_label, - "admin/delete_confirmation.html" - ], context) + return render( + request, + self.delete_confirmation_template + or [ + f"admin/{app_label}/{titleopts.object_name.lower()}/delete_confirmation.html", + "admin/%s/delete_confirmation.html" % app_label, + "admin/delete_confirmation.html", + ], + context, + ) @require_POST def change_innavigation(self, request, object_id): @@ -1291,9 +1287,9 @@ def get_tree(self, request): Used for lazy loading pages in cms.pagetree.js """ site = get_site(request) - pages = Page.objects.on_site(site).order_by('path') - node_id = re.sub(r'[^\d]', '', request.GET.get('nodeId', '')) or None - open_page_ids = [int(id) for id in request.GET.getlist('openNodes[]') if id.isdigit()] + pages = Page.objects.on_site(site).order_by("path") + node_id = re.sub(r"[^\d]", "", request.GET.get("nodeId", "")) or None + open_page_ids = [int(id) for id in request.GET.getlist("openNodes[]") if id.isdigit()] if node_id: page = get_object_or_404(pages, id=node_id) pages = page.get_descendant_pages().filter(Q(id__in=open_page_ids) | Q(parent__in=open_page_ids)) @@ -1305,9 +1301,9 @@ def get_tree(self, request): ) pages = pages.prefetch_related( Prefetch( - 'pagecontent_set', - to_attr='filtered_translations', - queryset=PageContent.admin_manager.get_queryset() , + "pagecontent_set", + to_attr="filtered_translations", + queryset=PageContent.admin_manager.get_queryset(), ), ) rows = self.get_tree_rows( @@ -1317,19 +1313,18 @@ def get_tree(self, request): depth=(page.depth + 1 if page else 1), follow_descendants=True, ) - return HttpResponse(''.join(rows)) + return HttpResponse("".join(rows)) - def get_tree_rows(self, request, pages, language, depth=1, - follow_descendants=True): + def get_tree_rows(self, request, pages, language, depth=1, follow_descendants=True): """ Used for rendering the page tree, inserts into context everything what we need for single item """ user = request.user site = get_site(request) - permissions_on = get_cms_setting('PERMISSION') + permissions_on = get_cms_setting("PERMISSION") template = get_template(self.page_tree_row_template) - is_popup = (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET) + is_popup = IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET languages = get_language_list(site.pk) user_can_add = page_permissions.user_can_add_subpage user_can_change = page_permissions.user_can_change_page @@ -1343,30 +1338,30 @@ def render_page_row(page): # TODO: check if this is really needed metadata = '{"valid_children": False, "draggable": False}' else: - metadata = '' + metadata = "" context = { - 'admin': self, - 'opts': self.opts, - 'site': site, - 'page': page, - 'page_content': page.get_admin_content(language), - 'ancestors': [page for page in page.get_cached_ancestors()], - 'descendants': [page for page in page.get_cached_descendants()], - 'request': request, - 'lang': language, - 'metadata': metadata, - 'page_languages': page.get_languages(), - 'preview_language': language, - 'follow_descendants': follow_descendants, - 'site_languages': languages, - 'is_popup': is_popup, - 'has_add_page_permission': user_can_add(user, target=page), - 'has_change_permission': user_can_change(request.user, page, site), - 'has_change_advanced_settings_permission': user_can_change_advanced(request.user, page, site), - 'has_move_page_permission': has_move_page_permission, + "admin": self, + "opts": self.opts, + "site": site, + "page": page, + "page_content": page.get_admin_content(language), + "ancestors": [page for page in page.get_cached_ancestors()], + "descendants": [page for page in page.get_cached_descendants()], + "request": request, + "lang": language, + "metadata": metadata, + "page_languages": page.get_languages(), + "preview_language": language, + "follow_descendants": follow_descendants, + "site_languages": languages, + "is_popup": is_popup, + "has_add_page_permission": user_can_add(user, target=page), + "has_change_permission": user_can_change(request.user, page, site), + "has_change_advanced_settings_permission": user_can_change_advanced(request.user, page, site), + "has_move_page_permission": has_move_page_permission, } - context['is_concrete'] = context['page_content'].language == language + context["is_concrete"] = context["page_content"].language == language return template.render(context) if follow_descendants: @@ -1399,11 +1394,9 @@ def get_indicator_menu(cls, request, page_content): ( _("Create Content"), # Entry "cms-icon-edit-new", # Optional icon - admin_reverse('cms_pagecontent_add') - + f'?cms_page={page_content.page.pk}&language={page_content.language}', # url + admin_reverse("cms_pagecontent_add") + + f"?cms_page={page_content.page.pk}&language={page_content.language}", # url None, # Optional add classes for ), ] return "", [] - - From dfb0483be1c8668629b02098ea7c7d0ba07f7a05 Mon Sep 17 00:00:00 2001 From: Jens-Erik Weber Date: Wed, 30 Oct 2024 21:12:10 +0100 Subject: [PATCH 2/3] fix: Make sure that the latest version is opened from the page overview in admin Without applying .latest_content() on the queryset it could happen that an old version was opened when clicking on the eye icon of a page in the pages overview. --- cms/admin/pageadmin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py index ba627c89dd4..ea907ea31bd 100644 --- a/cms/admin/pageadmin.py +++ b/cms/admin/pageadmin.py @@ -1303,7 +1303,7 @@ def get_tree(self, request): Prefetch( "pagecontent_set", to_attr="filtered_translations", - queryset=PageContent.admin_manager.get_queryset(), + queryset=PageContent.admin_manager.get_queryset().latest_content(), ), ) rows = self.get_tree_rows( From cbbaf888f58276e07eb29fff9648f153bc6879f3 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 30 Oct 2024 23:22:52 +0100 Subject: [PATCH 3/3] Fix: Undo format changes --- cms/admin/pageadmin.py | 541 +++++++++++++++++++++-------------------- 1 file changed, 273 insertions(+), 268 deletions(-) diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py index ea907ea31bd..7f3834cba3d 100644 --- a/cms/admin/pageadmin.py +++ b/cms/admin/pageadmin.py @@ -84,7 +84,7 @@ def get_site(request): - site_id = request.session.get("cms_admin_site") + site_id = request.session.get('cms_admin_site') if not site_id: return get_current_site() @@ -98,7 +98,7 @@ def get_site(request): @admin.register(Page) class PageAdmin(admin.ModelAdmin): - actions_menu_template = "admin/cms/page/tree/actions_dropdown.html" + actions_menu_template = 'admin/cms/page/tree/actions_dropdown.html' form = AdvancedSettingsForm copy_form = CopyPageForm @@ -147,7 +147,7 @@ def get_preserved_filters(self, request): lang = get_site_language_from_request(request, site_id=site.pk) if lang: - preserved_filters["language"] = lang + preserved_filters['language'] = lang return preserved_filters.urlencode() def get_queryset(self, request): @@ -166,22 +166,22 @@ def get_page_from_id(self, page_id): return page def get_urls(self): - """Get the admin urls""" + """Get the admin urls + """ info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" - def pat(regex, fn): - return re_path(regex, self.admin_site.admin_view(fn), name=f"{info}_{fn.__name__}") + return re_path(regex, self.admin_site.admin_view(fn), name=f'{info}_{fn.__name__}') url_patterns = [ - pat(r"^list/$", self.get_list), - pat(r"^([0-9]+)/actions-menu/$", self.actions_menu), - pat(r"^([0-9]+)/([a-z\-]+)/edit-field/$", self.edit_title_fields), - pat(r"^([0-9]+)/advanced-settings/$", self.advanced), - pat(r"^([0-9]+)/move-page/$", self.move_page), - pat(r"^([0-9]+)/copy-page/$", self.copy_page), - pat(r"^([0-9]+)/dialog/copy/$", self.get_copy_dialog), # copy dialog - pat(r"^([0-9]+)/permissions/$", self.get_permissions), - pat(r"^([0-9]+)/set-home/$", self.set_home), + pat(r'^list/$', self.get_list), + pat(r'^([0-9]+)/actions-menu/$', self.actions_menu), + pat(r'^([0-9]+)/([a-z\-]+)/edit-field/$', self.edit_title_fields), + pat(r'^([0-9]+)/advanced-settings/$', self.advanced), + pat(r'^([0-9]+)/move-page/$', self.move_page), + pat(r'^([0-9]+)/copy-page/$', self.copy_page), + pat(r'^([0-9]+)/dialog/copy/$', self.get_copy_dialog), # copy dialog + pat(r'^([0-9]+)/permissions/$', self.get_permissions), + pat(r'^([0-9]+)/set-home/$', self.set_home), ] if plugin_pool.registered_plugins: @@ -189,7 +189,7 @@ def pat(regex, fn): return url_patterns + super().get_urls() def get_inline_instances(self, request, obj=None): - if obj and get_cms_setting("PERMISSION"): + if obj and get_cms_setting('PERMISSION'): can_change_perms = self.has_change_permissions_permission(request, obj=obj) else: can_change_perms = False @@ -215,21 +215,21 @@ def actions_menu(self, request, object_id, extra_context=None): raise self._get_404_exception(object_id) site = get_site(request) - paste_enabled = request.GET.get("has_copy") or request.GET.get("has_cut") + paste_enabled = request.GET.get('has_copy') or request.GET.get('has_cut') context = { - "page": page, - "opts": self.opts, - "site": site, - "page_is_restricted": page.has_view_restrictions(site), - "paste_enabled": paste_enabled, - "has_add_permission": page_permissions.user_can_add_subpage(request.user, target=page), - "has_copy_page_permission": page_permissions.user_can_view_page_draft(request.user, page, site=site), - "has_change_permission": self.has_change_permission(request, obj=page), - "has_change_advanced_settings_permission": self.has_change_advanced_settings_permission(request, obj=page), - "has_change_permissions_permission": self.has_change_permissions_permission(request, obj=page), - "has_move_page_permission": self.has_move_page_permission(request, obj=page), - "has_delete_permission": self.has_delete_permission(request, obj=page), - "CMS_PERMISSION": get_cms_setting("PERMISSION"), + 'page': page, + 'opts': self.opts, + 'site': site, + 'page_is_restricted': page.has_view_restrictions(site), + 'paste_enabled': paste_enabled, + 'has_add_permission': page_permissions.user_can_add_subpage(request.user, target=page), + 'has_copy_page_permission': page_permissions.user_can_view_page_draft(request.user, page, site=site), + 'has_change_permission': self.has_change_permission(request, obj=page), + 'has_change_advanced_settings_permission': self.has_change_advanced_settings_permission(request, obj=page), + 'has_change_permissions_permission': self.has_change_permissions_permission(request, obj=page), + 'has_move_page_permission': self.has_move_page_permission(request, obj=page), + 'has_delete_permission': self.has_delete_permission(request, obj=page), + 'CMS_PERMISSION': get_cms_setting('PERMISSION'), } if extra_context: @@ -245,11 +245,11 @@ def advanced(self, request, object_id): if page is None: raise self._get_404_exception(object_id) - if get_cms_setting("PERMISSION"): + if get_cms_setting('PERMISSION'): show_permissions = self.has_change_permissions_permission(request, obj=page) else: show_permissions = False - context = {"title": _("Advanced Settings"), "show_permissions": show_permissions} + context = {'title': _("Advanced Settings"), 'show_permissions': show_permissions} return self.change_view(request, object_id, extra_context=context) def response_post_save_change(self, request, obj): @@ -265,9 +265,9 @@ def response_post_save_change(self, request, obj): if can_change_any_page: query = self.get_preserved_filters(request) - post_url = admin_reverse("cms_pagecontent_changelist") + "?" + query + post_url = admin_reverse('cms_pagecontent_changelist') + '?' + query else: - post_url = admin_reverse("index") + post_url = admin_reverse('index') return HttpResponseRedirect(post_url) @require_POST @@ -300,40 +300,45 @@ def set_home(self, request, object_id): # One or more pages affected by this operation was attached to an apphook. # As a result, fire the apphook reload signal to reload the url patterns. set_restart_trigger() - return HttpResponse("ok") + return HttpResponse('ok') def get_list(self, *args, **kwargs): """ - This view is used by the PageSmartLinkWidget as the user type to feed the autocomplete drop-down. + This view is used by the PageSmartLinkWidget as the user type to feed the autocomplete drop-down. """ request = args[0] - if request.headers.get("x-requested-with") == "XMLHttpRequest": - query_term = request.GET.get("q", "").strip("/") + if request.headers.get('x-requested-with') == 'XMLHttpRequest': + query_term = request.GET.get('q', '').strip('/') - language_code = request.GET.get("language_code", settings.LANGUAGE_CODE) + language_code = request.GET.get('language_code', settings.LANGUAGE_CODE) matching_published_pages = self.model.objects.filter( - Q(pagecontent_set__title__icontains=query_term, pagecontent_set__language=language_code) - | Q(urls__path__icontains=query_term, pagecontent_set__language=language_code) - | Q(pagecontent_set__menu_title__icontains=query_term, pagecontent_set__language=language_code) - | Q(pagecontent_set__page_title__icontains=query_term, pagecontent_set__language=language_code) + Q( + pagecontent_set__title__icontains=query_term, pagecontent_set__language=language_code + ) | Q( + urls__path__icontains=query_term, pagecontent_set__language=language_code + ) | Q( + pagecontent_set__menu_title__icontains=query_term, pagecontent_set__language=language_code + ) | Q( + pagecontent_set__page_title__icontains=query_term, pagecontent_set__language=language_code + ) ).distinct() results = [] for page in matching_published_pages: results.append( { - "path": page.get_path(language=language_code), - "title": page.get_title(language=language_code), - "redirect_url": page.get_absolute_url(language=language_code), + 'path': page.get_path(language=language_code), + 'title': page.get_title(language=language_code), + 'redirect_url': page.get_absolute_url(language=language_code) } ) - return HttpResponse(json.dumps(results), content_type="application/json") + return HttpResponse(json.dumps(results), content_type='application/json') return HttpResponseForbidden() def changelist_view(self, request, extra_context=None): parameter = "?" + request.GET.urlencode() if request.GET else "" - return HttpResponseRedirect(admin_reverse("cms_pagecontent_changelist") + parameter) + return HttpResponseRedirect(admin_reverse('cms_pagecontent_changelist') + parameter) def response_delete(self, request, obj_display, obj_id): """ @@ -351,18 +356,21 @@ def get_deleted_objects(self, objs, request): def delete_model(self, request, obj): operation_token = send_pre_page_operation( - request=request, operation=operations.DELETE_PAGE, obj=obj, sender=self.model + request=request, + operation=operations.DELETE_PAGE, + obj=obj, + sender=self.model ) cms_pages = [obj] if obj.is_branch: - descendant_ids = obj.get_descendants().values_list("id", flat=True) + descendant_ids = obj.get_descendants().values_list('id', flat=True) cms_pages.extend(self.model.objects.filter(id__in=descendant_ids)) # Delete all associated pages contents ct_page_content = ContentType.objects.get_for_model(PageContent) - page_content_objs = PageContent.admin_manager.filter(page__in=cms_pages).values_list("pk", flat=True) + page_content_objs = PageContent.admin_manager.filter(page__in=cms_pages).values_list('pk', flat=True) placeholders = Placeholder.objects.filter( content_type=ct_page_content, object_id__in=page_content_objs, @@ -387,26 +395,26 @@ def delete_model(self, request, obj): set_restart_trigger() def get_copy_dialog(self, request, page_id): - if not get_cms_setting("PERMISSION"): - return HttpResponse("") + if not get_cms_setting('PERMISSION'): + return HttpResponse('') page = self.get_page_from_id(page_id) if page is None: raise self._get_404_exception(page_id) - if request.method == "GET": + if request.method == 'GET': data = request.GET else: data = request.POST - target_id = data.get("target") + target_id = data.get('target') try: - source_site_id = data["source_site"] + source_site_id = data['source_site'] source_site = Site.objects.get(pk=source_site_id) except (KeyError, ObjectDoesNotExist): - return HttpResponseBadRequest("source_site is required") + return HttpResponseBadRequest('source_site is required') site = get_site(request) user = request.user @@ -427,20 +435,17 @@ def get_copy_dialog(self, request, page_id): raise PermissionDenied context = { - "dialog_id": "dialog-copy", - "form": CopyPermissionForm(), # class needs to be instantiated - "opts": self.opts, + 'dialog_id': 'dialog-copy', + 'form': CopyPermissionForm(), # class needs to be instantiated + 'opts': self.opts, } return render(request, "admin/cms/page/tree/copy_premissions.html", context) def _get_404_exception(self, object_id): - exception = Http404( - _("%(name)s object with primary key %(key)r does not exist.") - % { - "name": force_str(self.opts.verbose_name), - "key": escape(object_id), - } - ) + exception = Http404(_('%(name)s object with primary key %(key)r does not exist.') % { + 'name': force_str(self.opts.verbose_name), + 'key': escape(object_id), + }) return exception def has_view_permission(self, request, obj=None): @@ -502,12 +507,14 @@ def move_page(self, request, page_id, extra_context=None): if not form.is_valid(): return jsonify_request(HttpResponseBadRequest("error")) - target = form.cleaned_data["target"] + target = form.cleaned_data['target'] can_move_page = self.has_move_page_permission(request, obj=page) # Does the user have permissions to do this...? if not can_move_page or (target and not target.has_add_permission(user)): - message = _("Error! You don't have permissions to move this page. Please reload the page") + message = _( + "Error! You don't have permissions to move this page. Please reload the page" + ) return jsonify_request(HttpResponseForbidden(message)) operation_token = send_pre_page_operation( @@ -537,7 +544,7 @@ def get_permissions(self, request, page_id): raise self._get_404_exception(page_id) site = get_site(request) - PermissionRow = namedtuple("Permission", ["is_global", "can_change", "permission"]) + PermissionRow = namedtuple('Permission', ['is_global', 'can_change', 'permission']) global_permissions = GlobalPagePermission.objects.filter(sites__in=[site.pk]) can_change_global_permissions = permissions.user_can_change_global_permissions(user, site) @@ -550,7 +557,12 @@ def get_permissions(self, request, page_id): ) rows.append(row) - _page_permissions = PagePermission.objects.for_page(page).select_related("page") + _page_permissions = ( + PagePermission + .objects + .for_page(page) + .select_related('page') + ) if not can_change_global_permissions: allowed_pages = page_permissions.get_change_perm_tuples(user, site, check_global=False) @@ -570,11 +582,11 @@ def get_permissions(self, request, page_id): rows.append(row) context = { - "page": page, - "rows": rows, - "opts": self.opts, + 'page': page, + 'rows': rows, + 'opts': self.opts, } - return render(request, "admin/cms/page/permissions.html", context) + return render(request, 'admin/cms/page/permissions.html', context) @require_POST @transaction.atomic @@ -595,8 +607,8 @@ def copy_page(self, request, page_id): if not form.is_valid(): return jsonify_request(HttpResponseBadRequest("error")) - target = form.cleaned_data["target"] - source_site = form.cleaned_data["source_site"] + target = form.cleaned_data['target'] + source_site = form.cleaned_data['source_site'] # User can only copy pages he can see can_copy_page = page_permissions.user_can_view_page(user, page, source_site) @@ -624,7 +636,7 @@ def copy_page(self, request, page_id): return jsonify_request(HttpResponseBadRequest(message)) new_page = form.copy_page(user) - return HttpResponse(json.dumps({"id": new_page.pk}), content_type="application/json") + return HttpResponse(json.dumps({"id": new_page.pk}), content_type='application/json') def edit_title_fields(self, request, page_id, language): page = self.get_object(request, object_id=page_id) @@ -637,74 +649,70 @@ def edit_title_fields(self, request, page_id, language): raise self._get_404_exception(page_id) if not translation: - raise Http404("No translation matches requested language.") + raise Http404('No translation matches requested language.') saved_successfully = False - raw_fields = request.GET.get("edit_fields", "title") + raw_fields = request.GET.get("edit_fields", 'title') edit_fields = [field for field in raw_fields.split(",") if field in self.title_frontend_editable_fields] cancel_clicked = request.POST.get("_cancel", False) opts = PageContent._meta if not edit_fields: # Defaults to title - edit_fields = ("title",) + edit_fields = ('title',) class PageTitleForm(django.forms.ModelForm): """ Dynamic form showing only the fields to be edited """ - class Meta: model = PageContent fields = edit_fields - if not cancel_clicked and request.method == "POST": + if not cancel_clicked and request.method == 'POST': form = PageTitleForm(instance=translation, data=request.POST) if form.is_valid(): form.save() saved_successfully = True else: form = PageTitleForm(instance=translation) - admin_form = AdminForm( - form, fieldsets=[(None, {"fields": edit_fields})], prepopulated_fields={}, model_admin=self - ) + admin_form = AdminForm(form, fieldsets=[(None, {'fields': edit_fields})], prepopulated_fields={}, + model_admin=self) media = self.media + admin_form.media context = { - "CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), - "title": "Title", - "plugin": page, - "plugin_id": page.pk, - "adminform": admin_form, - "add": False, - "is_popup": True, - "media": media, - "opts": opts, - "change": True, - "save_as": False, - "has_add_permission": False, - "window_close_timeout": 10, + 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), + 'title': 'Title', + 'plugin': page, + 'plugin_id': page.pk, + 'adminform': admin_form, + 'add': False, + 'is_popup': True, + 'media': media, + 'opts': opts, + 'change': True, + 'save_as': False, + 'has_add_permission': False, + 'window_close_timeout': 10, } if cancel_clicked: # cancel button was clicked - context.update( - { - "cancel": True, - } - ) - return render(request, "admin/cms/page/plugin/confirm_form.html", context) - if not cancel_clicked and request.method == "POST" and saved_successfully: - return render(request, "admin/cms/page/plugin/confirm_form.html", context) - return render(request, "admin/cms/page/plugin/change_form.html", context) + context.update({ + 'cancel': True, + }) + return render(request, 'admin/cms/page/plugin/confirm_form.html', context) + if not cancel_clicked and request.method == 'POST' and saved_successfully: + return render(request, 'admin/cms/page/plugin/confirm_form.html', context) + return render(request, 'admin/cms/page/plugin/change_form.html', context) @admin.register(PageContent) class PageContentAdmin(admin.ModelAdmin): - ordering = ("page__path",) - search_fields = ("=id", "page__id", "page__urls__slug", "title", "page__reverse_id") + ordering = ('page__path',) + search_fields = ('=id', 'page__id', 'page__urls__slug', 'title', 'page__reverse_id') change_form_template = "admin/cms/page/change_form.html" change_list_template = "admin/cms/page/tree/base.html" - actions_menu_template = "admin/cms/page/tree/actions_dropdown.html" - page_tree_row_template = "admin/cms/page/tree/menu.html" + actions_menu_template = 'admin/cms/page/tree/actions_dropdown.html' + page_tree_row_template = 'admin/cms/page/tree/menu.html' form = AddPageForm add_form = form @@ -741,29 +749,29 @@ def get_preserved_filters(self, request): lang = get_site_language_from_request(request, site_id=site.pk) if lang: - preserved_filters["language"] = lang + preserved_filters['language'] = lang return preserved_filters.urlencode() def get_queryset(self, request): site = get_site(request) languages = get_language_list(site.pk) - queryset = super().get_queryset(request).select_related("page") + queryset = super().get_queryset(request).select_related('page') queryset = queryset.filter(language__in=languages, page__site=site) return queryset def get_urls(self): - """Get the admin urls""" + """Get the admin urls + """ info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" - def pat(regex, fn): - return re_path(regex, self.admin_site.admin_view(fn), name=f"{info}_{fn.__name__}") + return re_path(regex, self.admin_site.admin_view(fn), name=f'{info}_{fn.__name__}') url_patterns = [ - pat(r"^get-tree/$", self.get_tree), - pat(r"^([0-9]+)/duplicate/$", self.duplicate), - pat(r"^([0-9]+)/copy-language/$", self.copy_language), - pat(r"^([0-9]+)/change-navigation/$", self.change_innavigation), - pat(r"^([0-9]+)/change-template/$", self.change_template), + pat(r'^get-tree/$', self.get_tree), + pat(r'^([0-9]+)/duplicate/$', self.duplicate), + pat(r'^([0-9]+)/copy-language/$', self.copy_language), + pat(r'^([0-9]+)/change-navigation/$', self.change_innavigation), + pat(r'^([0-9]+)/change-template/$', self.change_template), ] return url_patterns + super().get_urls() @@ -774,13 +782,13 @@ def get_fieldsets(self, request, obj=None): fieldsets = form.fieldsets except AttributeError: fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) - fieldsets = [(None, {"fields": fields})] + fieldsets = [(None, {'fields': fields})] return fieldsets def get_form_class(self, request, obj=None, **kwargs): - if "change" in request.path_info: + if 'change' in request.path_info: return self.change_form - elif "duplicate" in request.path_info: + elif 'duplicate' in request.path_info: return self.duplicate_form return self.add_form @@ -789,7 +797,12 @@ def get_form(self, request, obj=None, **kwargs): Get PageForm for the Page model and modify its fields depending on the request. """ - form = super().get_form(request, obj, form=self.get_form_class(request, obj), **kwargs) + form = super().get_form( + request, + obj, + form=self.get_form_class(request, obj), + **kwargs + ) form._site = get_site(request) form._request = request return form @@ -817,61 +830,55 @@ def duplicate(self, request, object_id): if obj is None: raise self._get_404_exception(object_id) - if request.method == "GET": + if request.method == 'GET': # source is a field in the form # because its value is in the url, # we have to set the initial value manually request.GET = request.GET.copy() - request.GET["source"] = obj.page_id + request.GET['source'] = obj.page_id return self.add_view(request) - def add_view(self, request, form_url="", extra_context=None): + def add_view(self, request, form_url='', extra_context=None): site = get_site(request) language = get_site_language_from_request(request, site_id=site.pk) if extra_context is None: extra_context = {} - if "duplicate" in request.path_info: - extra_context.update( - { - "title": _("Add Page Copy"), - } - ) - elif "parent_page" in request.GET: - extra_context.update( - { - "title": _("New sub page"), - } - ) + if 'duplicate' in request.path_info: + extra_context.update({ + 'title': _("Add Page Copy"), + }) + elif 'parent_page' in request.GET: + extra_context.update({ + 'title': _("New sub page"), + }) else: - extra_context.update( - { - "title": _("New page"), - } - ) + extra_context.update({ + 'title': _("New page"), + }) try: - page_id = request.GET.get("cms_page") or request.POST.get("cms_page") + page_id = request.GET.get('cms_page') or request.POST.get('cms_page') page_id = IntegerField().clean(page_id) cms_page = Page.objects.get(pk=page_id) except (ValidationError, Page.DoesNotExist): cms_page = None if cms_page: - extra_context["cms_page"] = cms_page - extra_context["language_tabs"] = get_language_tuple(site.pk) - extra_context["filled_languages"] = self.get_filled_languages(request, cms_page) - extra_context["show_language_tabs"] = len(extra_context["language_tabs"]) - extra_context["language"] = language + extra_context['cms_page'] = cms_page + extra_context['language_tabs'] = get_language_tuple(site.pk) + extra_context['filled_languages'] = self.get_filled_languages(request, cms_page) + extra_context['show_language_tabs'] = len(extra_context['language_tabs']) + extra_context['language'] = language return super().add_view(request, form_url, extra_context=extra_context) - def change_view(self, request, object_id, form_url="", extra_context=None): + def change_view(self, request, object_id, form_url='', extra_context=None): """ The 'change' admin view for the PageContent model. """ if extra_context is None: - extra_context = {"basic_info": True} + extra_context = {'basic_info': True} obj = self.get_object(request, object_id=object_id) @@ -880,19 +887,19 @@ def change_view(self, request, object_id, form_url="", extra_context=None): site = get_site(request) context = { - "cms_page": obj.page, - "CMS_PERMISSION": get_cms_setting("PERMISSION"), - "can_change": self.has_change_permission(request, obj=obj), - "language": obj.language, - "language_tabs": get_language_tuple(site.pk), - "filled_languages": self.get_filled_languages(request, obj.page), + 'cms_page': obj.page, + 'CMS_PERMISSION': get_cms_setting('PERMISSION'), + 'can_change': self.has_change_permission(request, obj=obj), + 'language': obj.language, + 'language_tabs': get_language_tuple(site.pk), + 'filled_languages': self.get_filled_languages(request, obj.page) } - context["show_language_tabs"] = len(context["language_tabs"]) + context['show_language_tabs'] = len(context['language_tabs']) context.update(extra_context or {}) - if "basic_info" in extra_context: + if 'basic_info' in extra_context: _has_advanced_settings_perm = self.has_change_advanced_settings_permission(request, obj=obj) - context["can_change_advanced_settings"] = _has_advanced_settings_perm + context['can_change_advanced_settings'] = _has_advanced_settings_perm return super().change_view(request, object_id, form_url=form_url, extra_context=context) @@ -902,14 +909,14 @@ def response_add(self, request, obj): from django.core.cache import cache from cms.cache.permissions import get_cache_key, get_cache_permission_version - - cache.delete(get_cache_key(request.user, "change_page"), version=get_cache_permission_version()) + cache.delete(get_cache_key(request.user, 'change_page'), version=get_cache_permission_version()) # redirect to the edit view if added from the toolbar url = get_object_edit_url(obj) # Redirects to preview if necessary return HttpResponse(MODAL_HTML_REDIRECT.format(url=url)) return super().response_add(request, obj) + def get_filled_languages(self, request, page): site_id = get_site(request).pk filled_languages = page.get_languages() @@ -917,18 +924,15 @@ def get_filled_languages(self, request, page): return [lang for lang in filled_languages if lang in allowed_languages] def _get_404_exception(self, object_id): - exception = Http404( - _("%(name)s object with primary key %(key)r does not exist.") - % { - "name": force_str(self.opts.verbose_name), - "key": escape(object_id), - } - ) + exception = Http404(_('%(name)s object with primary key %(key)r does not exist.') % { + 'name': force_str(self.opts.verbose_name), + 'key': escape(object_id), + }) return exception def _has_add_permission_from_request(self, request): site = get_site(request) - if parent_id := request.GET.get("parent_page"): + if parent_id := request.GET.get('parent_page'): try: parent_id = IntegerField().clean(parent_id) parent_item = Page.objects.get(id=parent_id) @@ -1020,15 +1024,15 @@ def changelist_view(self, request, extra_context=None): if not self.has_change_permission(request, obj=None): raise PermissionDenied - if request.method == "POST" and "site" in request.POST: - site_id = request.POST["site"] + if request.method == 'POST' and 'site' in request.POST: + site_id = request.POST['site'] if site_id.isdigit() and Site.objects.filter(pk=site_id).exists(): - request.session["cms_admin_site"] = site_id + request.session['cms_admin_site'] = site_id site = get_site(request) language = get_site_language_from_request(request, site_id=site.pk) - query = request.GET.get("q", "") + query = request.GET.get('q', '') page_contents = self.get_queryset(request) page_contents, _ = self.get_search_results(request, page_contents, query) changelist_form = self.changelist_form(request.GET) @@ -1044,19 +1048,23 @@ def changelist_view(self, request, extra_context=None): # something is screwed up with the database, so display an error # page. if ERROR_FLAG in request.GET.keys(): - return SimpleTemplateResponse( - "admin/invalid_setup.html", - { - "title": _("Database error"), - }, - ) - return HttpResponseRedirect(request.path + "?" + ERROR_FLAG + "=1") - - pages = Page.objects.on_site(site).filter(pagecontent_set__in=page_contents).distinct().order_by("path") + return SimpleTemplateResponse('admin/invalid_setup.html', { + 'title': _('Database error'), + }) + return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1') + + pages = ( + Page + .objects + .on_site(site) + .filter(pagecontent_set__in=page_contents) + .distinct() + .order_by('path') + ) pages = pages.prefetch_related( Prefetch( - "pagecontent_set", - to_attr="filtered_translations", + 'pagecontent_set', + to_attr='filtered_translations', queryset=page_contents, ), ) @@ -1068,28 +1076,26 @@ def changelist_view(self, request, extra_context=None): has_items = pages.exists() context = self.admin_site.each_context(request) - context.update( - { - "opts": self.model._meta, - "media": self.media, - "CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), - "CMS_PERMISSION": get_cms_setting("PERMISSION"), - "site_languages": get_language_tuple(site.pk), - "preview_language": language, - "changelist_form": changelist_form, - "cms_current_site": site, - "has_add_permission": self.has_add_permission(request), - "module_name": force_str(self.model._meta.verbose_name_plural), - "admin": self, - "tree": { - "site": site, - "query": query, - "is_filtered": changelist_form.is_filtered(), - "items": pages, - "has_items": has_items, - }, - } - ) + context.update({ + 'opts': self.model._meta, + 'media': self.media, + 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), + 'CMS_PERMISSION': get_cms_setting('PERMISSION'), + 'site_languages': get_language_tuple(site.pk), + 'preview_language': language, + 'changelist_form': changelist_form, + 'cms_current_site': site, + 'has_add_permission': self.has_add_permission(request), + 'module_name': force_str(self.model._meta.verbose_name_plural), + 'admin': self, + 'tree': { + 'site': site, + 'query': query, + 'is_filtered': changelist_form.is_filtered(), + 'items': pages, + 'has_items': has_items, + }, + }) context.update(extra_context or {}) request.current_app = self.admin_site.name return TemplateResponse(request, self.change_list_template, context) @@ -1099,23 +1105,24 @@ def change_template(self, request, object_id): page_content = self.get_object(request, object_id=object_id) if not self.has_change_permission(request, obj=page_content): - raise PermissionDenied("No permissions to change the template") + raise PermissionDenied('No permissions to change the template') if page_content is None: raise self._get_404_exception(object_id) if not self.has_change_advanced_settings_permission(request, obj=page_content): - raise PermissionDenied("No permissions to change the template") + raise PermissionDenied('No permissions to change the template') to_template = request.POST.get("template", None) - if get_cms_setting("TEMPLATES"): - if to_template not in dict(get_cms_setting("TEMPLATES")): + if get_cms_setting('TEMPLATES'): + if to_template not in dict(get_cms_setting('TEMPLATES')): return HttpResponseBadRequest(_("Template not valid")) else: - if to_template not in (placeholder_set[0] for placeholder_set in get_cms_setting("PLACEHOLDERS")): + if to_template not in (placeholder_set[0] for placeholder_set in get_cms_setting('PLACEHOLDERS')): return HttpResponseBadRequest(_("Placeholder selection not valid")) + page_content.template = to_template page_content.save() @@ -1124,7 +1131,7 @@ def change_template(self, request, object_id): @require_POST @transaction.atomic def copy_language(self, request, object_id): - target_language = request.POST.get("target_language") + target_language = request.POST.get('target_language') source_page_content = self.get_object(request, object_id=object_id) if not self.has_change_permission(request, obj=source_page_content): @@ -1165,7 +1172,7 @@ def delete_view(self, request, object_id, extra_context=None): raise self._get_404_exception(object_id) if not len(list(page.get_languages())) > 1: - return HttpResponseBadRequest("There only exists one translation for this page") + return HttpResponseBadRequest('There only exists one translation for this page') titleopts = PageContent._meta app_label = titleopts.app_label @@ -1191,9 +1198,11 @@ def delete_view(self, request, object_id, extra_context=None): )[:3] to_delete_objects = [to_delete_urls, to_delete_plugins, to_delete_translations] - perms_needed = set(list(perms_needed_url) + list(perms_needed_translation) + list(perms_needed_plugins)) + perms_needed = set( + list(perms_needed_url) + list(perms_needed_translation) + list(perms_needed_plugins) + ) - if request.method == "POST": + if request.method == 'POST': if perms_needed: raise PermissionDenied @@ -1202,11 +1211,11 @@ def delete_view(self, request, object_id, extra_context=None): operation=operations.DELETE_PAGE_TRANSLATION, obj=page, translation=page_content, - sender=self.model, + sender=self.model ) - message = _("Title and plugins with language %(language)s was deleted") % { - "language": force_str(get_language_object(language)["name"]) + message = _('Title and plugins with language %(language)s was deleted') % { + 'language': force_str(get_language_object(language)['name']) } messages.success(request, message) @@ -1227,10 +1236,10 @@ def delete_view(self, request, object_id, extra_context=None): ) if not self.has_change_permission(request, None): - return HttpResponseRedirect(admin_reverse("index")) + return HttpResponseRedirect(admin_reverse('index')) - redirect_to = self.get_admin_url("changelist") - redirect_to += f"?language={request_language}" + redirect_to = self.get_admin_url('changelist') + redirect_to += f'?language={request_language}' return HttpResponseRedirect(redirect_to) context = { @@ -1240,21 +1249,16 @@ def delete_view(self, request, object_id, extra_context=None): "deleted_objects": to_delete_objects, "perms_lacking": perms_needed, "opts": self.opts, - "root_path": admin_reverse("index"), + "root_path": admin_reverse('index'), "app_label": app_label, } context.update(extra_context or {}) request.current_app = self.admin_site.name - return render( - request, - self.delete_confirmation_template - or [ - f"admin/{app_label}/{titleopts.object_name.lower()}/delete_confirmation.html", - "admin/%s/delete_confirmation.html" % app_label, - "admin/delete_confirmation.html", - ], - context, - ) + return render(request, self.delete_confirmation_template or [ + f"admin/{app_label}/{titleopts.object_name.lower()}/delete_confirmation.html", + "admin/%s/delete_confirmation.html" % app_label, + "admin/delete_confirmation.html" + ], context) @require_POST def change_innavigation(self, request, object_id): @@ -1287,9 +1291,9 @@ def get_tree(self, request): Used for lazy loading pages in cms.pagetree.js """ site = get_site(request) - pages = Page.objects.on_site(site).order_by("path") - node_id = re.sub(r"[^\d]", "", request.GET.get("nodeId", "")) or None - open_page_ids = [int(id) for id in request.GET.getlist("openNodes[]") if id.isdigit()] + pages = Page.objects.on_site(site).order_by('path') + node_id = re.sub(r'[^\d]', '', request.GET.get('nodeId', '')) or None + open_page_ids = [int(id) for id in request.GET.getlist('openNodes[]') if id.isdigit()] if node_id: page = get_object_or_404(pages, id=node_id) pages = page.get_descendant_pages().filter(Q(id__in=open_page_ids) | Q(parent__in=open_page_ids)) @@ -1301,8 +1305,8 @@ def get_tree(self, request): ) pages = pages.prefetch_related( Prefetch( - "pagecontent_set", - to_attr="filtered_translations", + 'pagecontent_set', + to_attr='filtered_translations', queryset=PageContent.admin_manager.get_queryset().latest_content(), ), ) @@ -1313,18 +1317,19 @@ def get_tree(self, request): depth=(page.depth + 1 if page else 1), follow_descendants=True, ) - return HttpResponse("".join(rows)) + return HttpResponse(''.join(rows)) - def get_tree_rows(self, request, pages, language, depth=1, follow_descendants=True): + def get_tree_rows(self, request, pages, language, depth=1, + follow_descendants=True): """ Used for rendering the page tree, inserts into context everything what we need for single item """ user = request.user site = get_site(request) - permissions_on = get_cms_setting("PERMISSION") + permissions_on = get_cms_setting('PERMISSION') template = get_template(self.page_tree_row_template) - is_popup = IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET + is_popup = (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET) languages = get_language_list(site.pk) user_can_add = page_permissions.user_can_add_subpage user_can_change = page_permissions.user_can_change_page @@ -1338,30 +1343,30 @@ def render_page_row(page): # TODO: check if this is really needed metadata = '{"valid_children": False, "draggable": False}' else: - metadata = "" + metadata = '' context = { - "admin": self, - "opts": self.opts, - "site": site, - "page": page, - "page_content": page.get_admin_content(language), - "ancestors": [page for page in page.get_cached_ancestors()], - "descendants": [page for page in page.get_cached_descendants()], - "request": request, - "lang": language, - "metadata": metadata, - "page_languages": page.get_languages(), - "preview_language": language, - "follow_descendants": follow_descendants, - "site_languages": languages, - "is_popup": is_popup, - "has_add_page_permission": user_can_add(user, target=page), - "has_change_permission": user_can_change(request.user, page, site), - "has_change_advanced_settings_permission": user_can_change_advanced(request.user, page, site), - "has_move_page_permission": has_move_page_permission, + 'admin': self, + 'opts': self.opts, + 'site': site, + 'page': page, + 'page_content': page.get_admin_content(language), + 'ancestors': [page for page in page.get_cached_ancestors()], + 'descendants': [page for page in page.get_cached_descendants()], + 'request': request, + 'lang': language, + 'metadata': metadata, + 'page_languages': page.get_languages(), + 'preview_language': language, + 'follow_descendants': follow_descendants, + 'site_languages': languages, + 'is_popup': is_popup, + 'has_add_page_permission': user_can_add(user, target=page), + 'has_change_permission': user_can_change(request.user, page, site), + 'has_change_advanced_settings_permission': user_can_change_advanced(request.user, page, site), + 'has_move_page_permission': has_move_page_permission, } - context["is_concrete"] = context["page_content"].language == language + context['is_concrete'] = context['page_content'].language == language return template.render(context) if follow_descendants: @@ -1394,8 +1399,8 @@ def get_indicator_menu(cls, request, page_content): ( _("Create Content"), # Entry "cms-icon-edit-new", # Optional icon - admin_reverse("cms_pagecontent_add") - + f"?cms_page={page_content.page.pk}&language={page_content.language}", # url + admin_reverse('cms_pagecontent_add') + + f'?cms_page={page_content.page.pk}&language={page_content.language}', # url None, # Optional add classes for ), ]