Skip to content
This repository was archived by the owner on Mar 26, 2025. It is now read-only.

Commit c8d5fce

Browse files
authored
fix: Delay importing models.CMSPlugin in utils. (#637)
1 parent 9ac4c15 commit c8d5fce

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ Changelog
55
Unreleased
66
==========
77

8+
* Fix `468 <https://github.com/django-cms/djangocms-text-ckeditor/issues/468>`_ via `637 <https://github.com/django-cms/djangocms-text-ckeditor/pull/637>`_: Delay importing models.CMSPlugin in utils to allow adding an HTMLField to a custom user model.
9+
10+
811
5.1.1 (2022-06-22)
912
==================
1013

djangocms_text_ckeditor/utils.py

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@
88
from django.template.loader import render_to_string
99
from django.utils.functional import LazyObject
1010

11-
from cms.models import CMSPlugin
12-
1311
from classytags.utils import flatten_context
1412

1513

1614
OBJ_ADMIN_RE_PATTERN = r'<cms-plugin .*?\bid="(?P<pk>\d+)".*?>.*?</cms-plugin>'
17-
OBJ_ADMIN_WITH_CONTENT_RE_PATTERN = r'<cms-plugin .*?\bid="(?P<pk>\d+)".*?>(?P<content>.*?)</cms-plugin>'
15+
OBJ_ADMIN_WITH_CONTENT_RE_PATTERN = (
16+
r'<cms-plugin .*?\bid="(?P<pk>\d+)".*?>(?P<content>.*?)</cms-plugin>'
17+
)
1818
OBJ_ADMIN_RE = re.compile(OBJ_ADMIN_RE_PATTERN, flags=re.DOTALL)
1919

2020

2121
def _render_cms_plugin(plugin, context):
2222
context = flatten_context(context)
23-
context['plugin'] = plugin
23+
context["plugin"] = plugin
2424

2525
# This my fellow ckeditor enthusiasts is a hack..
2626

@@ -34,9 +34,9 @@ def _render_cms_plugin(plugin, context):
3434
# and thus calls context processors AND render the plugin manually with the context
3535
# after it's been bound to a template.
3636
response = render_to_string(
37-
'cms/plugins/render_plugin_preview.html',
37+
"cms/plugins/render_plugin_preview.html",
3838
context,
39-
request=context['request'],
39+
request=context["request"],
4040
)
4141
return response
4242

@@ -49,10 +49,11 @@ def wrapped_view(*args, **kwargs):
4949
response = view_func(*args, **kwargs)
5050
response._random_comment_exempt = True
5151
return response
52+
5253
return wraps(view_func, assigned=WRAPPER_ASSIGNMENTS)(wrapped_view)
5354

5455

55-
def plugin_to_tag(obj, content='', admin=False):
56+
def plugin_to_tag(obj, content="", admin=False):
5657
plugin_attrs = OrderedDict(
5758
id=obj.pk,
5859
icon_alt=force_escape(obj.get_instance_icon_alt()),
@@ -62,12 +63,12 @@ def plugin_to_tag(obj, content='', admin=False):
6263
if admin:
6364
# Include extra attributes when rendering on the admin
6465
plugin_class = obj.get_plugin_class()
65-
preview = getattr(plugin_class, 'text_editor_preview', True)
66+
preview = getattr(plugin_class, "text_editor_preview", True)
6667
plugin_tag = (
6768
'<cms-plugin render-plugin=%(preview)s alt="%(icon_alt)s "'
6869
'title="%(icon_alt)s" id="%(id)d">%(content)s</cms-plugin>'
6970
)
70-
plugin_attrs['preview'] = 'true' if preview else 'false'
71+
plugin_attrs["preview"] = "true" if preview else "false"
7172
else:
7273
plugin_tag = (
7374
'<cms-plugin alt="%(icon_alt)s "'
@@ -79,10 +80,11 @@ def plugin_to_tag(obj, content='', admin=False):
7980
def plugin_tags_to_id_list(text, regex=OBJ_ADMIN_RE):
8081
def _find_plugins():
8182
for tag in regex.finditer(text):
82-
plugin_id = tag.groupdict().get('pk')
83+
plugin_id = tag.groupdict().get("pk")
8384

8485
if plugin_id:
8586
yield plugin_id
87+
8688
return [int(_id) for _id in _find_plugins()]
8789

8890

@@ -96,59 +98,67 @@ def _plugin_tags_to_html(text, output_func):
9698

9799
def _render_tag(m):
98100
try:
99-
plugin_id = int(m.groupdict()['pk'])
101+
plugin_id = int(m.groupdict()["pk"])
100102
obj = plugins_by_id[plugin_id]
101103
except KeyError:
102104
# Object must have been deleted. It cannot be rendered to
103105
# end user so just remove it from the HTML altogether
104-
return ''
106+
return ""
105107
else:
106108
obj._render_meta.text_enabled = True
107109
return output_func(obj, m)
110+
108111
return OBJ_ADMIN_RE.sub(_render_tag, text)
109112

110113

111114
def plugin_tags_to_user_html(text, context):
112115
def _render_plugin(obj, match):
113116
return _render_cms_plugin(obj, context)
117+
114118
return _plugin_tags_to_html(text, output_func=_render_plugin)
115119

116120

117121
def plugin_tags_to_admin_html(text, context):
118122
def _render_plugin(obj, match):
119123
plugin_content = _render_cms_plugin(obj, context)
120124
return plugin_to_tag(obj, content=plugin_content, admin=True)
125+
121126
return _plugin_tags_to_html(text, output_func=_render_plugin)
122127

123128

124129
def plugin_tags_to_db(text):
125130
def _strip_plugin_content(obj, match):
126131
return plugin_to_tag(obj).strip()
132+
127133
return _plugin_tags_to_html(text, output_func=_strip_plugin_content)
128134

129135

130136
def replace_plugin_tags(text, id_dict, regex=OBJ_ADMIN_RE):
137+
from cms.models import CMSPlugin
138+
131139
plugins_by_id = CMSPlugin.objects.in_bulk(id_dict.values())
132140

133141
def _replace_tag(m):
134142
try:
135-
plugin_id = int(m.groupdict()['pk'])
143+
plugin_id = int(m.groupdict()["pk"])
136144
new_id = id_dict[plugin_id]
137145
plugin = plugins_by_id[new_id]
138146
except KeyError:
139147
# Object must have been deleted. It cannot be rendered to
140148
# end user, or edited, so just remove it from the HTML
141149
# altogether
142-
return ''
150+
return ""
143151
return plugin_to_tag(plugin)
152+
144153
return regex.sub(_replace_tag, text)
145154

146155

147156
def get_plugins_from_text(text, regex=OBJ_ADMIN_RE):
157+
from cms.models import CMSPlugin
148158
from cms.utils.plugins import downcast_plugins
149159

150160
plugin_ids = plugin_tags_to_id_list(text, regex)
151-
plugins = CMSPlugin.objects.filter(pk__in=plugin_ids).select_related('placeholder')
161+
plugins = CMSPlugin.objects.filter(pk__in=plugin_ids).select_related("placeholder")
152162
plugin_list = downcast_plugins(plugins, select_placeholder=True)
153163
return {plugin.pk: plugin for plugin in plugin_list}
154164

@@ -157,14 +167,16 @@ def get_plugins_from_text(text, regex=OBJ_ADMIN_RE):
157167
The following class is taken from https://github.com/jezdez/django/compare/feature/staticfiles-templatetag
158168
and should be removed and replaced by the django-core version in 1.4
159169
"""
160-
default_storage = 'django.contrib.staticfiles.storage.StaticFilesStorage'
170+
default_storage = "django.contrib.staticfiles.storage.StaticFilesStorage"
161171

162172

163173
class ConfiguredStorage(LazyObject):
164-
165174
def _setup(self):
166175
from django.conf import settings
167-
self._wrapped = get_storage_class(getattr(settings, 'STATICFILES_STORAGE', default_storage))()
176+
177+
self._wrapped = get_storage_class(
178+
getattr(settings, "STATICFILES_STORAGE", default_storage)
179+
)()
168180

169181

170182
configured_storage = ConfiguredStorage()
@@ -175,5 +187,5 @@ def static_url(path):
175187
Helper that prefixes a URL with STATIC_URL and cms
176188
"""
177189
if not path:
178-
return ''
179-
return configured_storage.url(os.path.join('', path))
190+
return ""
191+
return configured_storage.url(os.path.join("", path))

0 commit comments

Comments
 (0)