|
1 | 1 | from django.conf import settings
|
2 | 2 | from django.conf.urls import url
|
3 | 3 | 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 |
4 | 8 | from django.db import models
|
5 | 9 | from django.forms import Textarea
|
| 10 | +from django.utils.translation import gettext as _ |
6 | 11 |
|
7 | 12 | from cms.utils.permissions import get_model_permission_codename
|
8 | 13 |
|
9 | 14 | from .cms_config import SnippetCMSAppConfig
|
10 | 15 | from .forms import SnippetForm
|
11 | 16 | from .models import Snippet
|
12 |
| -from .views import SnippetPreviewView |
13 | 17 |
|
14 | 18 |
|
15 | 19 | # Use the version mixin if djangocms-versioning is installed and enabled
|
|
18 | 22 |
|
19 | 23 | try:
|
20 | 24 | from djangocms_versioning.admin import ExtendedVersionAdminMixin
|
| 25 | + |
21 | 26 | if djangocms_versioning_enabled:
|
22 | 27 | snippet_admin_classes.insert(0, ExtendedVersionAdminMixin)
|
23 | 28 | except ImportError:
|
@@ -73,15 +78,76 @@ def get_list_display_links(self, request, list_display):
|
73 | 78 | self.list_display_links = (None,)
|
74 | 79 | return self.list_display_links
|
75 | 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 | + |
76 | 142 | def get_urls(self):
|
77 | 143 | info = self.model._meta.app_label, self.model._meta.model_name
|
78 | 144 | return [
|
79 |
| - url( |
80 |
| - r"^(?P<snippet_id>\d+)/preview/$", |
81 |
| - self.admin_site.admin_view(SnippetPreviewView.as_view()), |
82 |
| - name="{}_{}_preview".format(*info), |
83 |
| - ), |
84 |
| - ] + 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() |
85 | 151 |
|
86 | 152 | def has_delete_permission(self, request, obj=None):
|
87 | 153 | """
|
|
0 commit comments