Skip to content

Commit 35bf3b7

Browse files
committed
Fix: Bring up to date with target
2 parents 6a8e934 + c25b365 commit 35bf3b7

File tree

9 files changed

+194
-58
lines changed

9 files changed

+194
-58
lines changed

CHANGELOG.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ Unreleased
66
==========
77
* fix: Removed auto-escape from snippet preview template, tags will now be rendered on the page.
88

9+
4.0.0.dev4 (2022-02-03)
10+
=======================
11+
12+
* feat: Preview icon renders form in read only mode
13+
14+
15+
4.0.0.dev3 (2022-01-11)
16+
=======================
17+
18+
* fix: Snippet plugin added to a page now displays name instead of ID
19+
* fix: Slug field on list display for admin should only be displayed when versioning is not available
20+
* fix: Removed unused contents within templates, reducing the clutter within version compare views. Previously this was causing a lot of junk to be included in the version comparison, this will now be reduced.
21+
22+
923
4.0.0.dev2 (2021-12-22)
1024
=======================
1125

djangocms_snippet/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
__version__ = '4.0.0.dev2'
1+
__version__ = '4.0.0.dev4'
22

33
default_app_config = 'djangocms_snippet.apps.SnippetConfig'

djangocms_snippet/admin.py

Lines changed: 104 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
from django.conf import settings
22
from django.conf.urls import url
33
from django.contrib import admin
4+
from django.contrib.admin import helpers
5+
from django.contrib.admin.exceptions import DisallowedModelAdminToField
6+
from django.contrib.admin.options import IS_POPUP_VAR, TO_FIELD_VAR
7+
from django.contrib.admin.utils import flatten_fieldsets, unquote
48
from django.db import models
59
from django.forms import Textarea
10+
from django.utils.translation import gettext as _
611

712
from cms.utils.permissions import get_model_permission_codename
813

914
from .cms_config import SnippetCMSAppConfig
1015
from .forms import SnippetForm
1116
from .models import Snippet
12-
from .views import SnippetPreviewView
1317

1418

1519
# Use the version mixin if djangocms-versioning is installed and enabled
@@ -22,13 +26,12 @@
2226
if djangocms_versioning_enabled:
2327
snippet_admin_classes.insert(0, ExtendedVersionAdminMixin)
2428
except ImportError:
25-
pass
29+
djangocms_versioning_enabled = False
2630

2731

2832
class SnippetAdmin(*snippet_admin_classes):
29-
list_display = ('slug', 'name')
30-
search_fields = ['slug', 'name']
31-
prepopulated_fields = {'slug': ('name',)}
33+
list_display = ('name',)
34+
search_fields = ['name']
3235
change_form_template = 'djangocms_snippet/admin/change_form.html'
3336
text_area_attrs = {
3437
'rows': 20,
@@ -46,15 +49,105 @@ class SnippetAdmin(*snippet_admin_classes):
4649
class Meta:
4750
model = Snippet
4851

52+
def get_list_display(self, request):
53+
list_display = super().get_list_display(request)
54+
list_display = list(list_display)
55+
56+
if not djangocms_versioning_enabled:
57+
list_display.insert(0, 'slug')
58+
59+
list_display = tuple(list_display)
60+
return list_display
61+
62+
def get_search_fields(self, request):
63+
search_fields = super().get_search_fields(request)
64+
if not djangocms_versioning_enabled:
65+
search_fields.append('slug')
66+
return search_fields
67+
68+
def get_prepopulated_fields(self, obj, request):
69+
prepopulated_fields = super().get_prepopulated_fields(request)
70+
if not djangocms_versioning_enabled:
71+
prepopulated_fields = {'slug': ('name',)}
72+
return prepopulated_fields
73+
74+
def get_list_display_links(self, request, list_display):
75+
if not djangocms_versioning_enabled:
76+
return list(list_display)[:1]
77+
else:
78+
self.list_display_links = (None,)
79+
return self.list_display_links
80+
81+
def preview_view(self, request, snippet_id=None, form_url='', extra_context=None):
82+
"""
83+
Custom preview endpoint to display a change form in read only mode
84+
Solution based on django changeform view implementation
85+
https://github.com/django/django/blob/4b8e9492d9003ca357a4402f831112dd72efd2f8/django/contrib/admin/options.py#L1553
86+
"""
87+
to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
88+
89+
if to_field and not self.to_field_allowed(request, to_field):
90+
raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)
91+
92+
model = self.model
93+
opts = model._meta
94+
95+
obj = self.get_object(request, unquote(snippet_id), to_field)
96+
97+
if obj is None:
98+
return self._get_obj_does_not_exist_redirect(request, opts, snippet_id)
99+
100+
fieldsets = self.get_fieldsets(request, obj)
101+
ModelForm = self.get_form(
102+
request, obj, change=False, fields=flatten_fieldsets(fieldsets)
103+
)
104+
form = ModelForm(instance=obj)
105+
formsets, inline_instances = self._create_formsets(request, obj, change=True)
106+
107+
readonly_fields = flatten_fieldsets(fieldsets)
108+
109+
adminForm = helpers.AdminForm(
110+
form,
111+
list(fieldsets),
112+
# Clear prepopulated fields on a view-only form to avoid a crash.
113+
{},
114+
readonly_fields,
115+
model_admin=self)
116+
media = self.media + adminForm.media
117+
118+
inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj)
119+
for inline_formset in inline_formsets:
120+
media = media + inline_formset.media
121+
122+
title = _('View %s')
123+
context = {
124+
**self.admin_site.each_context(request),
125+
'title': title % opts.verbose_name,
126+
'subtitle': str(obj) if obj else None,
127+
'adminform': adminForm,
128+
'object_id': snippet_id,
129+
'original': obj,
130+
'is_popup': IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET,
131+
'to_field': to_field,
132+
'media': media,
133+
'inline_admin_formsets': inline_formsets,
134+
'errors': [],
135+
'preserved_filters': self.get_preserved_filters(request),
136+
}
137+
138+
context.update(extra_context or {})
139+
140+
return self.render_change_form(request, context, add=False, change=False, obj=obj, form_url=form_url)
141+
49142
def get_urls(self):
50143
info = self.model._meta.app_label, self.model._meta.model_name
51144
return [
52-
url(
53-
r"^(?P<snippet_id>\d+)/preview/$",
54-
self.admin_site.admin_view(SnippetPreviewView.as_view()),
55-
name="{}_{}_preview".format(*info),
56-
),
57-
] + super().get_urls()
145+
url(
146+
r"^(?P<snippet_id>\d+)/preview/$",
147+
self.admin_site.admin_view(self.preview_view),
148+
name="{}_{}_preview".format(*info),
149+
),
150+
] + super().get_urls()
58151

59152
def has_delete_permission(self, request, obj=None):
60153
"""

djangocms_snippet/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class SnippetPtr(CMSPlugin):
106106

107107
search_fields = ['snippet__html'] if SEARCH_ENABLED else []
108108

109+
def get_short_description(self):
110+
snippet_label = SnippetGrouper.objects.filter(pk=self.snippet_grouper.pk).first()
111+
return snippet_label
112+
109113
class Meta:
110114
verbose_name = _('Snippet Ptr')
111115
verbose_name_plural = _('Snippet Ptrs')
Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1 @@
1-
{% extends "admin/base_site.html" %}
2-
{% load static %}
31
{{ snippet.html|safe|escape }}
4-
5-
{% block extrastyle %}
6-
{{ block.super }}
7-
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}">
8-
{% endblock %}
9-
10-
{% block coltype %}flex{% endblock %}
11-
12-
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %}
13-
14-
{% block content %}
15-
{{ snippet.html }}
16-
{% endblock %}

djangocms_snippet/views.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

tests/test_admin.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def test_admin_list_display_with_versioning(self):
5959
self.snippet_admin.__class__.__bases__, (ExtendedVersionAdminMixin, admin.ModelAdmin)
6060
)
6161
self.assertEqual(
62-
list_display[:-1], ('slug', 'name', 'get_author', 'get_modified_date', 'get_versioning_state')
62+
list_display[:-1], ('name', 'get_author', 'get_modified_date', 'get_versioning_state')
6363
)
6464
self.assertEqual(list_display[-1].short_description, 'actions')
6565
self.assertIn("function ExtendedVersionAdminMixin._list_actions", list_display[-1].__str__())
@@ -179,3 +179,51 @@ def test_admin_form_edit_when_locked(self):
179179
self.assertContains(response, '<div class="readonly">Test Snippet</div>')
180180
# We should have the same number of snippets as before
181181
self.assertEqual(Snippet.objects.count(), 1)
182+
183+
@override_settings(DJANGOCMS_SNIPPET_VERSIONING_ENABLED=False)
184+
def test_slug_colomn_should_hyperlinked_with_versioning_disabled(self):
185+
"""
186+
Slug column should be visible and hyperlinked when versioning is disabled
187+
"""
188+
admin.site.unregister(Snippet)
189+
reload(cms_config)
190+
reload(snippet_admin)
191+
192+
with self.login_user_context(self.get_superuser()):
193+
response = self.client.get(self.changelist_url)
194+
self.assertContains(response, '<th class="field-slug"><a href="/en/admin/djangocms_snippet/'
195+
'snippet/1/change/">test-snippet</a></th>')
196+
197+
@override_settings(DJANGOCMS_SNIPPET_VERSIONING_ENABLED=True)
198+
def test_name_colomn_should_not_be_hyperlinked_with_versioning_enabled(self):
199+
"""
200+
Name column should be visible and not hyperlinked when versioning is enabled.
201+
Slug column should not be visible when versioning is enabled.
202+
"""
203+
admin.site.unregister(Snippet)
204+
reload(cms_config)
205+
reload(snippet_admin)
206+
207+
with self.login_user_context(self.get_superuser()):
208+
response = self.client.get(self.changelist_url)
209+
self.assertContains(response, '<td class="field-name">Test Snippet</td>')
210+
self.assertNotContains(response, '<th class="field-slug"><a href="/en/admin/djangocms_snippet/'
211+
'snippet/1/change/">test-snippet</a></th>')
212+
213+
def test_preview_renders_read_only_fields(self):
214+
"""
215+
Check that the preview endpoint is rendered in read only mode
216+
"""
217+
self.snippet_version.publish(user=self.superuser)
218+
with self.login_user_context(self.superuser):
219+
edit_url = reverse("admin:djangocms_snippet_snippet_preview", args=(self.snippet.id,),)
220+
response = self.client.get(edit_url)
221+
222+
# Snippet name
223+
self.assertContains(response, '<div class="readonly">Test Snippet</div>')
224+
# Snippet slug
225+
self.assertContains(response, '<div class="readonly">test-snippet</div>')
226+
# Snippet HTML
227+
self.assertContains(response, '<div class="readonly">&lt;h1&gt;This is a test&lt;/h1&gt;</div>')
228+
# Snippet template
229+
self.assertContains(response, '<div class="readonly"></div>')

tests/test_plugins.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from cms.api import add_plugin, create_page
44
from cms.models import PageContent
55
from cms.test_utils.testcases import CMSTestCase
6-
from cms.toolbar.utils import get_object_edit_url
6+
from cms.toolbar.utils import get_object_edit_url, get_object_structure_url
77

88
from djangocms_snippet.models import Snippet, SnippetGrouper
99
from djangocms_versioning.models import Version
@@ -290,3 +290,21 @@ def test_published_snippet_and_page_live_url_rendering(self):
290290

291291
self.assertContains(response, "<p>Published snippet</p>")
292292
self.assertNotIn("Draft snippet", str(response.content))
293+
294+
def test_correct_name_is_displayed_for_snippet_component_on_page(self):
295+
"""
296+
If a component is added to the page, it should show the snippet name and not ID
297+
"""
298+
add_plugin(
299+
self.draft_pagecontent.placeholders.get(slot="content"),
300+
"SnippetPlugin",
301+
self.language,
302+
snippet_grouper=self.draft_snippet.snippet_grouper,
303+
)
304+
305+
# Request structure endpoint on page
306+
request_url = get_object_structure_url(self.draft_pagecontent, "en")
307+
with self.login_user_context(self.superuser):
308+
response = self.client.get(request_url)
309+
310+
self.assertContains(response, "<strong>Snippet</strong> plugin_snippet</span>")

tests/test_views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ def test_preview_renders_html(self):
2626
# the response will contain character entity references.
2727
self.assertContains(response, "&lt;h1&gt;Test Title&lt;/h1&gt;&lt;br&gt;&lt;p&gt;Test paragraph&lt;/p&gt;")
2828

29-
def test_preview_raises_404_no_snippet(self):
29+
def test_preview_raises_302_no_snippet(self):
3030
"""
31-
With no Snippet to preview, a 404 will be raised
31+
With no Snippet to preview, a 302 will be raised and the user will be redirected to the admin
3232
"""
3333
preview_url = admin_reverse(
3434
"djangocms_snippet_snippet_preview",
@@ -37,4 +37,4 @@ def test_preview_raises_404_no_snippet(self):
3737
with self.login_user_context(self.user):
3838
response = self.client.get(preview_url)
3939

40-
self.assertEqual(response.status_code, 404)
40+
self.assertEqual(response.status_code, 302)

0 commit comments

Comments
 (0)