-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathplugin_rendering.py
86 lines (71 loc) · 3.43 KB
/
plugin_rendering.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from cms import __version__ as cms_version
from cms.plugin_rendering import ContentRenderer, StructureRenderer
from cms.utils.placeholder import rescan_placeholders_for_obj
from django.utils.functional import cached_property
from . import versionables
from .constants import DRAFT, PUBLISHED
def prefetch_versioned_related_objects(instance, toolbar):
instance, plugin = instance.get_plugin_instance()
candidate_fields = [
f for f in instance._meta.get_fields() if f.is_relation and not f.auto_created
]
for field in candidate_fields:
try:
versionable = versionables.for_grouper(field.remote_field.model)
except KeyError:
continue
if toolbar.edit_mode_active or toolbar.preview_mode_active:
qs = versionable.content_model._base_manager.filter(
versions__state__in=(DRAFT, PUBLISHED)
).order_by("versions__state")
else:
qs = versionable.content_model.objects.all()
related_field = getattr(instance, field.name)
if related_field:
filters = {versionable.grouper_field_name: related_field}
# TODO Figure out grouping values-awareness
# for extra fields other than hardcoded 'language'
if "language" in versionable.extra_grouping_fields:
filters["language"] = toolbar.request_language
qs = qs.filter(**filters)
prefetch_cache = {versionable.grouper_field.remote_field.name: qs}
related_field._prefetched_objects_cache = prefetch_cache
class VersionContentRenderer(ContentRenderer):
def render_plugin(self, instance, context, placeholder=None, editable=False):
prefetch_versioned_related_objects(instance, self.toolbar)
return super().render_plugin(instance, context, placeholder, editable)
if cms_version in ("4.1.0", "4.1.1"):
# Only needed for CMS 4.1.0 and 4.1.1 which have fix #7924 not merged
# With #7924, page-specific rendering works well with versioning.
def render_obj_placeholder(
self, slot, context, inherit, nodelist=None, editable=True
):
# FIXME This is an ad-hoc solution for page-specific rendering
# code, which by default doesn't work well with versioning.
# Remove this method once the issue is fixed.
from cms.models import Placeholder
current_obj = self.toolbar.get_object()
# Not page, therefore we will use toolbar object as
# the current object and render the placeholder
rescan_placeholders_for_obj(current_obj)
placeholder = Placeholder.objects.get_for_obj(current_obj).get(slot=slot)
content = self.render_placeholder(
placeholder,
context=context,
page=current_obj,
editable=editable,
use_cache=True,
nodelist=None,
)
return content
class VersionStructureRenderer(StructureRenderer):
def render_plugin(self, instance, page=None):
prefetch_versioned_related_objects(instance, self.toolbar)
return super().render_plugin(instance, page)
class CMSToolbarVersioningMixin:
@cached_property
def content_renderer(self):
return VersionContentRenderer(request=self.request)
@cached_property
def structure_renderer(self):
return VersionStructureRenderer(request=self.request)