8000 fix: Grouper admin raised AttributeError when used outside the admin … · django-cms/django-cms@c50f28d · GitHub
[go: up one dir, main page]

Skip to content

Commit c50f28d

Browse files
fsbraunGithub Release Actionvinitkumar
committed
fix: Grouper admin raised AttributeError when used outside the admin views (#8067)
* Fix: GrouperModelAdmin raised an AttributeError if used outside the admin app * Fixed: Page.__str__ returns page title with admin_manager * feat: Format `Page.__str__` as "My title (/path/to/page/)" * Update tests for new str method of Page * Simplify str --------- Co-authored-by: Github Release Action <info@django-cms.org> Co-authored-by: Vinit Kumar <mail@vinitkumar.me>
1 parent dcecb46 commit c50f28d

File tree

7 files changed

+25
-42
lines changed

7 files changed

+25
-42
lines changed

cms/admin/pageadmin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class PageAdmin(admin.ModelAdmin):
103103
copy_form = CopyPageForm
104104
move_form = MovePageForm
105105
inlines = PERMISSION_ADMIN_INLINES
106-
title_frontend_editable_fields = ['title', 'menu_title', 'page_title']
106+
search_fields = ('=id', 'urls__slug', 'pagecontent_set__title', 'reverse_id')
107107

108108
def has_add_permission(self, request):
109109
return False

cms/admin/utils.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,16 +405,24 @@ def get_grouping_from_request(self, request: HttpRequest) -> None:
405405
@property
406406
def current_content_filters(self) -> typing.Dict[str, typing.Any]:
407407
"""Filters needed to get the correct content model instance"""
408-
return {field: getattr(self, field) for field in self.extra_grouping_fields}
408+
return {field: getattr(self, field, self.get_extra_grouping_field(field)) for field in self.extra_grouping_fields}
409409

410410
def get_language(self) -> str:
411-
"""Hook on how to get the current language. By default, Django provides it."""
412-
return get_language()
411+
"""Hook on how to get the current language. By default, if it is set as a
412+
property, use the property, otherwise let Django provide it."""
413+
return getattr(self, "language", get_language())
413414

414415
def get_language_tuple(self) -> typing.Tuple[typing.Tuple[str, str], ...]:
415416
"""Hook on how to get all available languages for the language selector."""
416417
return get_language_tuple()
417418

419+
def get_extra_grouping_field(self, field):
420+
"""Retrieves the current value for grouping fields - by default by calling self.get_<field>, e.g.,
421+
self.get_language(). If those are not implemented, this method will fail."""
422+
if callable(getattr(self, f"get_{field}", None)):
423+
return getattr(self, f"get_{field}")()
424+
raise ValueError("Cannot get extra grouping field")
425+
418426
def get_changelist(self, request: HttpRequest, **kwargs) -> type:
419427
"""Allow for extra grouping fields as a non-filter parameter"""
420428
return type(

cms/forms/validators.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,9 @@ def validate_url_uniqueness(site, path, language, user_language=None, exclude_pa
5757
message = gettext('Page %(conflict_page)s has the same url \'%(url)s\' as current page "%(instance)s".')
5858
else:
5959
message = gettext('Page %(conflict_page)s has the same url \'%(url)s\' as current page.')
60-
message = message % {'conflict_page': conflict_url, 'url': path, 'instance': exclude_page}
60+
message = message % {
61+
'conflict_page': conflict_url,
62+
'url': path,
63+
'instance': exclude_page.get_title(language) if exclude_page else ''
64+
}
6165
raise ValidationError(mark_safe(message))

cms/tests/test_admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def test_search_fields(self):
165165
if not admin_instance.search_fields:
166166
continue
167167
url = admin_reverse('cms_%s_changelist' % model._meta.model_name)
168-
response = self.client.get('%s?q=1' % url)
168+
response = self.client.get('%s?q=1' % url, follow=True) # Page redirects to PageContent
169169
errmsg = response.content
170170
self.assertEqual(response.status_code, 200, errmsg)
171171

cms/tests/test_grouper_admin.py

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django.templatetags.static import static
55
from django.utils.crypto import get_random_string
66
from django.utils.translation import get_language, override as force_language
7+
from django.utils.translation import get_language, override as force_language
78

89
from cms.admin.utils import CONTENT_PREFIX
910
from cms.test_utils.project.sampleapp.models import (
@@ -178,7 +179,7 @@ def test_extra_grouping_field_fixed(self):
178179
current_content_filters = self.admin.current_content_filters
179180

180181
self.assertEqual(admin_language, expected_language)
181-
self.assertEqual(current_content_filters["language"], expected_language)
182+
self.assertEqual(current_content_filters["language"], expected_language)
182183

183184
def test_extra_grouping_field_current(self):
184185
"""Extra grouping fields (language) when not set return current default correctly"""
@@ -191,39 +192,6 @@ def test_extra_grouping_field_current(self):
191192
self.assertEqual(admin_language, expected_language)
192193
self.assertEqual(current_content_filters["language"], expected_language)
193194

194-
def test_prepopulated_fields_pass_checks(self):
195-
"""Prepopulated fields work for content field"""
196-
# Arrange
197-
admin = copy.copy(self.admin)
198-
admin.prepopulated_fields = dict(
199-
category_name=["category_name"], # Both key and value from GrouperModel
200-
some_field=["content__secret_greeting"], # Value from ContentModel
201-
content__secret_greeting=["category_name"], # Key from GrouperModel
202-
content__region=["content__secret_greeting"], # Both key and value from ContentModel
203-
)
204-
205-
# Act
206-
check_results = admin.check()
207-
208-
# Assert
209-
self.assertEqual(check_results, []) # No errors
210-
211-
def test_invalid_prepopulated_content_fields_fail_checks(self):
212-
"""Prepopulated fields with invalid content field names fail checks"""
213-
# Arrange
214-
admin = copy.copy(self.admin)
215-
admin.prepopulated_fields = dict(
216-
some_field=["content__public_greeting"], # Value from ContentModel: 1 error
217-
content__public_greeting=["category_name"], # Key from GrouperModel: 1 error
218-
content__country=["content__public_greeting"], # Both key and value from ContentModel: 2 errors
219-
)
220-
221-
# Act
222-
check_results = admin.check()
223-
224-
# Assert
225-
self.assertEqual(len(check_results), 4) # No errors
226-
227195

228196
class GrouperChangeListTestCase(SetupMixin, CMSTestCase):
229197
def test_language_selector(self):

cms/tests/test_log_entries.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from cms.models import Page, Placeholder, UserSettings
88
from cms.test_utils.testcases import URL_CMS_PAGE_MOVE, CMSTestCase
99
from cms.utils import get_current_site
10+
from cms.utils.i18n import force_language
1011
from cms.wizards.forms import WizardStep2BaseForm, step2_form_factory
1112

1213
# Snippet to create wizard page taken from: test_wizards.py
@@ -214,6 +215,8 @@ def test_log_for_delete_translation(self):
214215
title_en = "page_a"
215216
page = create_page(title_en, "nav_playground.html", "en")
216217
create_page_content(language='de', title="other title %s" % title_en, page=page)
218+
with force_language("de"): # The remaining language
219+
expected_entry = str(page)
217220
endpoint = self.get_page_delete_translation_uri('en', page)
218221
post_data = {'post': 'yes', 'language': 'en'}
219222

@@ -233,7 +236,7 @@ def test_log_for_delete_translation(self):
233236
# Check the object id is set correctly
234237
self.assertEqual(str(page.pk), log_entry.object_id)
235238
# Check the object_repr is set correctly
236-
self.assertEqual(str(page), log_entry.object_repr)
239+
self.assertEqual(expected_entry, log_entry.object_repr)
237240
# Check that the correct user created the log
238241
self.assertEqual(self._admin_user.pk, log_entry.user_id)
239242

cms/utils/placeholder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from sekizai.helpers import get_varname
2222

2323
from cms.exceptions import DuplicatePlaceholderWarning
24-
from cms.models import Placeholder
24+
from cms.models import EmptyPageContent, Placeholder
2525
from cms.utils.conf import get_cms_setting
2626

2727
RANGE_START = 128

0 commit comments

Comments
 (0)
0