django-prose-editor 0.20.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_prose_editor-0.20.0/.gitignore +27 -0
- django_prose_editor-0.20.0/LICENSE +45 -0
- django_prose_editor-0.20.0/PKG-INFO +70 -0
- django_prose_editor-0.20.0/README.rst +29 -0
- django_prose_editor-0.20.0/django_prose_editor/.gitignore +1 -0
- django_prose_editor-0.20.0/django_prose_editor/__init__.py +1 -0
- django_prose_editor-0.20.0/django_prose_editor/apps.py +9 -0
- django_prose_editor-0.20.0/django_prose_editor/checks.py +239 -0
- django_prose_editor-0.20.0/django_prose_editor/config.py +426 -0
- django_prose_editor-0.20.0/django_prose_editor/fields.py +178 -0
- django_prose_editor-0.20.0/django_prose_editor/locale/de/LC_MESSAGES/django.mo +0 -0
- django_prose_editor-0.20.0/django_prose_editor/locale/de/LC_MESSAGES/django.po +34 -0
- django_prose_editor-0.20.0/django_prose_editor/locale/de/LC_MESSAGES/djangojs.mo +0 -0
- django_prose_editor-0.20.0/django_prose_editor/locale/de/LC_MESSAGES/djangojs.po +141 -0
- django_prose_editor-0.20.0/django_prose_editor/sanitized.py +21 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/configurable.js +2 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/configurable.js.map +1 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/default.js +2 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/default.js.map +1 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/editor.css +2 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/editor.css.map +1 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/editor.js +117 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/editor.js.map +1 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/material-icons.css +2 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/material-icons.css.map +1 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/material-icons.woff2 +0 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/overrides.css +2 -0
- django_prose_editor-0.20.0/django_prose_editor/static/django_prose_editor/overrides.css.map +1 -0
- django_prose_editor-0.20.0/django_prose_editor/widgets.py +120 -0
- django_prose_editor-0.20.0/pyproject.toml +142 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
*~
|
|
2
|
+
\#*#
|
|
3
|
+
/build
|
|
4
|
+
/.bundle
|
|
5
|
+
.coverage
|
|
6
|
+
/data.db
|
|
7
|
+
/dist
|
|
8
|
+
.DS_Store
|
|
9
|
+
/dump.rdb
|
|
10
|
+
*.egg-info
|
|
11
|
+
/.env
|
|
12
|
+
/htdocs/e
|
|
13
|
+
/.idea
|
|
14
|
+
/log
|
|
15
|
+
/media
|
|
16
|
+
/node_modules
|
|
17
|
+
*.pyc
|
|
18
|
+
/static
|
|
19
|
+
.*.sw*
|
|
20
|
+
/tmp
|
|
21
|
+
.tox
|
|
22
|
+
/vendor
|
|
23
|
+
/venv
|
|
24
|
+
/.vscode
|
|
25
|
+
yarn-error.log
|
|
26
|
+
build
|
|
27
|
+
test-results
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Feinheit AG
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
--------------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
This software includes or depends on the following third-party libraries:
|
|
34
|
+
|
|
35
|
+
ProseMirror (MIT License)
|
|
36
|
+
Copyright (c) 2015-2017 by Marijn Haverbeke and others
|
|
37
|
+
https://prosemirror.net/
|
|
38
|
+
|
|
39
|
+
Tiptap (MIT License)
|
|
40
|
+
Copyright (c) 2024 Tiptap GmbH
|
|
41
|
+
https://tiptap.dev/
|
|
42
|
+
|
|
43
|
+
Material Design Icons (Apache License 2.0)
|
|
44
|
+
Copyright Google Inc.
|
|
45
|
+
https://fonts.google.com/icons
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-prose-editor
|
|
3
|
+
Version: 0.20.0
|
|
4
|
+
Summary: Prose editor for the Django admin based on ProseMirror
|
|
5
|
+
Project-URL: Documentation, https://django-prose-editor.readthedocs.io/
|
|
6
|
+
Project-URL: Homepage, https://github.com/matthiask/django-prose-editor/
|
|
7
|
+
Author-email: Matthias Kestenholz <mk@feinheit.ch>
|
|
8
|
+
License: BSD-3-Clause
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Framework :: Django
|
|
12
|
+
Classifier: Framework :: Django :: 4.2
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
24
|
+
Classifier: Topic :: Software Development
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Requires-Dist: django-js-asset>=3.1.2
|
|
28
|
+
Requires-Dist: django>=4.2
|
|
29
|
+
Provides-Extra: sanitize
|
|
30
|
+
Requires-Dist: nh3>=0.3; extra == 'sanitize'
|
|
31
|
+
Provides-Extra: tests
|
|
32
|
+
Requires-Dist: asgiref; extra == 'tests'
|
|
33
|
+
Requires-Dist: coverage; extra == 'tests'
|
|
34
|
+
Requires-Dist: nh3>=0.3; extra == 'tests'
|
|
35
|
+
Requires-Dist: pytest; extra == 'tests'
|
|
36
|
+
Requires-Dist: pytest-asyncio; extra == 'tests'
|
|
37
|
+
Requires-Dist: pytest-cov; extra == 'tests'
|
|
38
|
+
Requires-Dist: pytest-django; extra == 'tests'
|
|
39
|
+
Requires-Dist: pytest-playwright; extra == 'tests'
|
|
40
|
+
Description-Content-Type: text/x-rst
|
|
41
|
+
|
|
42
|
+
===================
|
|
43
|
+
django-prose-editor
|
|
44
|
+
===================
|
|
45
|
+
|
|
46
|
+
Prose editor for the Django admin based on ProseMirror and Tiptap. `Announcement blog post <https://406.ch/writing/django-prose-editor-prose-editing-component-for-the-django-admin/>`__.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Intro
|
|
50
|
+
=====
|
|
51
|
+
|
|
52
|
+
After installing the package (using ``pip install
|
|
53
|
+
django-prose-editor[sanitize]``) the following should get you started:
|
|
54
|
+
|
|
55
|
+
.. code-block:: python
|
|
56
|
+
|
|
57
|
+
from django_prose_editor.fields import ProseEditorField
|
|
58
|
+
|
|
59
|
+
content = ProseEditorField(
|
|
60
|
+
extensions={
|
|
61
|
+
"Bold": True,
|
|
62
|
+
"Italic": True,
|
|
63
|
+
"BulletList": True,
|
|
64
|
+
"ListItem": True,
|
|
65
|
+
"Link": True,
|
|
66
|
+
},
|
|
67
|
+
sanitize=True, # Server side sanitization is strongly recommended.
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
Check the `documentation <https://django-prose-editor.readthedocs.io>`__.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
===================
|
|
2
|
+
django-prose-editor
|
|
3
|
+
===================
|
|
4
|
+
|
|
5
|
+
Prose editor for the Django admin based on ProseMirror and Tiptap. `Announcement blog post <https://406.ch/writing/django-prose-editor-prose-editing-component-for-the-django-admin/>`__.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Intro
|
|
9
|
+
=====
|
|
10
|
+
|
|
11
|
+
After installing the package (using ``pip install
|
|
12
|
+
django-prose-editor[sanitize]``) the following should get you started:
|
|
13
|
+
|
|
14
|
+
.. code-block:: python
|
|
15
|
+
|
|
16
|
+
from django_prose_editor.fields import ProseEditorField
|
|
17
|
+
|
|
18
|
+
content = ProseEditorField(
|
|
19
|
+
extensions={
|
|
20
|
+
"Bold": True,
|
|
21
|
+
"Italic": True,
|
|
22
|
+
"BulletList": True,
|
|
23
|
+
"ListItem": True,
|
|
24
|
+
"Link": True,
|
|
25
|
+
},
|
|
26
|
+
sanitize=True, # Server side sanitization is strongly recommended.
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
Check the `documentation <https://django-prose-editor.readthedocs.io>`__.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
lib/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.20.0"
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from django.apps import apps
|
|
2
|
+
from django.conf import settings
|
|
3
|
+
from django.core.checks import Error, Warning, register
|
|
4
|
+
|
|
5
|
+
from django_prose_editor.fields import ProseEditorField, _actually_empty
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@register()
|
|
9
|
+
def check_js_preset_configuration(app_configs, **kwargs):
|
|
10
|
+
"""
|
|
11
|
+
Check that the 'default' JavaScript preset is not being overridden in settings.
|
|
12
|
+
"""
|
|
13
|
+
errors = []
|
|
14
|
+
|
|
15
|
+
# Main setting
|
|
16
|
+
if hasattr(settings, "DJANGO_PROSE_EDITOR_PRESETS"):
|
|
17
|
+
presets = settings.DJANGO_PROSE_EDITOR_PRESETS
|
|
18
|
+
if "default" in presets:
|
|
19
|
+
errors.append(
|
|
20
|
+
Error(
|
|
21
|
+
'Overriding the "default" preset in DJANGO_PROSE_EDITOR_PRESETS is not allowed.',
|
|
22
|
+
hint="Remove the 'default' key from your DJANGO_PROSE_EDITOR_PRESETS setting.",
|
|
23
|
+
obj=settings,
|
|
24
|
+
id="django_prose_editor.E001",
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if "configurable" in presets:
|
|
29
|
+
errors.append(
|
|
30
|
+
Error(
|
|
31
|
+
'Overriding the "configurable" preset in DJANGO_PROSE_EDITOR_PRESETS is not allowed.',
|
|
32
|
+
hint="Remove the 'configurable' key from your DJANGO_PROSE_EDITOR_PRESETS setting.",
|
|
33
|
+
obj=settings,
|
|
34
|
+
id="django_prose_editor.E002",
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
return errors
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@register()
|
|
42
|
+
def check_extensions_parameter(app_configs, **kwargs):
|
|
43
|
+
"""
|
|
44
|
+
Check for usage of 'extensions' (because we want that!)
|
|
45
|
+
"""
|
|
46
|
+
warnings = []
|
|
47
|
+
|
|
48
|
+
# Get models to check based on provided app_configs or all models
|
|
49
|
+
models_to_check = []
|
|
50
|
+
if app_configs:
|
|
51
|
+
for app_config in app_configs:
|
|
52
|
+
models_to_check.extend(app_config.get_models())
|
|
53
|
+
else:
|
|
54
|
+
models_to_check = apps.get_models()
|
|
55
|
+
|
|
56
|
+
# Check models for fields using deprecated config
|
|
57
|
+
for model in models_to_check:
|
|
58
|
+
for field in model._meta.fields:
|
|
59
|
+
if isinstance(field, ProseEditorField):
|
|
60
|
+
# Check if this field is using legacy config (no 'extensions' key)
|
|
61
|
+
if (
|
|
62
|
+
not isinstance(field.config, dict)
|
|
63
|
+
or "extensions" not in field.config
|
|
64
|
+
):
|
|
65
|
+
warnings.append(
|
|
66
|
+
Warning(
|
|
67
|
+
"This ProseEditorField is using the legacy configuration format which is "
|
|
68
|
+
"deprecated and will be removed in a future version. Add the 'extensions' "
|
|
69
|
+
"configuration explicitly to use the new configuration format.",
|
|
70
|
+
obj=f"{model._meta.label}.{field.name}",
|
|
71
|
+
id="django_prose_editor.W001",
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return warnings
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@register()
|
|
79
|
+
def check_custom_extensions_configuration(app_configs, **kwargs):
|
|
80
|
+
"""
|
|
81
|
+
Check that custom extensions are properly configured.
|
|
82
|
+
"""
|
|
83
|
+
errors = []
|
|
84
|
+
|
|
85
|
+
# Check if custom extensions are defined
|
|
86
|
+
if hasattr(settings, "DJANGO_PROSE_EDITOR_EXTENSIONS"):
|
|
87
|
+
extensions = settings.DJANGO_PROSE_EDITOR_EXTENSIONS
|
|
88
|
+
|
|
89
|
+
# Check that extensions is a list
|
|
90
|
+
if not isinstance(extensions, list):
|
|
91
|
+
errors.append(
|
|
92
|
+
Error(
|
|
93
|
+
"DJANGO_PROSE_EDITOR_EXTENSIONS must be a list of dictionaries.",
|
|
94
|
+
hint="Configure DJANGO_PROSE_EDITOR_EXTENSIONS as a list of dictionaries, each with 'js' and 'extensions' keys.",
|
|
95
|
+
obj=settings,
|
|
96
|
+
id="django_prose_editor.E003",
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
return errors
|
|
100
|
+
|
|
101
|
+
# Check each extension group
|
|
102
|
+
for i, extension_group in enumerate(extensions):
|
|
103
|
+
if not isinstance(extension_group, dict):
|
|
104
|
+
errors.append(
|
|
105
|
+
Error(
|
|
106
|
+
f"Extension group at index {i} must be a dictionary.",
|
|
107
|
+
hint="Each extension group must be a dictionary with 'js' and 'extensions' keys.",
|
|
108
|
+
obj=settings,
|
|
109
|
+
id="django_prose_editor.E004",
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
# Check that required keys are present
|
|
115
|
+
if "extensions" not in extension_group:
|
|
116
|
+
errors.append(
|
|
117
|
+
Error(
|
|
118
|
+
f"Extension group at index {i} is missing the required 'extensions' key.",
|
|
119
|
+
hint="Each extension group must have an 'extensions' key mapping extension names to processors.",
|
|
120
|
+
obj=settings,
|
|
121
|
+
id="django_prose_editor.E005",
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
continue
|
|
125
|
+
|
|
126
|
+
if "js" not in extension_group:
|
|
127
|
+
errors.append(
|
|
128
|
+
Warning(
|
|
129
|
+
f"Extension group at index {i} is missing the 'js' key.",
|
|
130
|
+
hint="Each extension group should have a 'js' key listing JavaScript assets for the extensions.",
|
|
131
|
+
obj=settings,
|
|
132
|
+
id="django_prose_editor.W002",
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Check the extensions dictionary
|
|
137
|
+
extensions_dict = extension_group["extensions"]
|
|
138
|
+
if not isinstance(extensions_dict, dict):
|
|
139
|
+
errors.append(
|
|
140
|
+
Error(
|
|
141
|
+
f"The 'extensions' key in extension group at index {i} must be a dictionary.",
|
|
142
|
+
hint="The 'extensions' key should map extension names to processor callables or dotted paths.",
|
|
143
|
+
obj=settings,
|
|
144
|
+
id="django_prose_editor.E006",
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
# Check each processor
|
|
150
|
+
for extension_name, processor in extensions_dict.items():
|
|
151
|
+
# Check if the processor is a string (dotted path) or callable
|
|
152
|
+
if not (callable(processor) or isinstance(processor, str)):
|
|
153
|
+
errors.append(
|
|
154
|
+
Error(
|
|
155
|
+
f'Processor for extension "{extension_name}" in group {i} must be a callable or a dotted path string.',
|
|
156
|
+
hint="Each processor must be either a callable or a dotted import path.",
|
|
157
|
+
obj=settings,
|
|
158
|
+
id="django_prose_editor.E007",
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# If it's a string, verify it looks like a dotted path
|
|
163
|
+
if isinstance(processor, str) and "." not in processor:
|
|
164
|
+
errors.append(
|
|
165
|
+
Warning(
|
|
166
|
+
f'Processor path "{processor}" for extension "{extension_name}" in group {i} may not be a valid dotted import path.',
|
|
167
|
+
hint="The processor should be a dotted import path like 'myapp.processors.my_processor'.",
|
|
168
|
+
obj=settings,
|
|
169
|
+
id="django_prose_editor.W003",
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# Check the js assets list
|
|
174
|
+
js_assets = extension_group.get("js", [])
|
|
175
|
+
if not isinstance(js_assets, (list, tuple)):
|
|
176
|
+
errors.append(
|
|
177
|
+
Error(
|
|
178
|
+
f"The 'js' key in extension group at index {i} must be a list.",
|
|
179
|
+
hint="The 'js' key should be a list of JavaScript asset URLs.",
|
|
180
|
+
obj=settings,
|
|
181
|
+
id="django_prose_editor.E008",
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return errors
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@register()
|
|
189
|
+
def check_sanitization_enabled(app_configs, **kwargs):
|
|
190
|
+
"""
|
|
191
|
+
Check that all ProseEditorField instances have sanitization enabled.
|
|
192
|
+
"""
|
|
193
|
+
warnings = []
|
|
194
|
+
|
|
195
|
+
# Get models to check based on provided app_configs or all models
|
|
196
|
+
models_to_check = []
|
|
197
|
+
if app_configs:
|
|
198
|
+
for app_config in app_configs:
|
|
199
|
+
models_to_check.extend(app_config.get_models())
|
|
200
|
+
else:
|
|
201
|
+
models_to_check = apps.get_models()
|
|
202
|
+
|
|
203
|
+
# Check all models for ProseEditorField without sanitization
|
|
204
|
+
for model in models_to_check:
|
|
205
|
+
for field in model._meta.fields:
|
|
206
|
+
if isinstance(field, ProseEditorField):
|
|
207
|
+
# Check if sanitization is disabled or set to the identity function
|
|
208
|
+
if field.sanitize == _actually_empty:
|
|
209
|
+
# Different messages based on whether using extensions or legacy config
|
|
210
|
+
if isinstance(field.config, dict) and "extensions" in field.config:
|
|
211
|
+
message = (
|
|
212
|
+
"This ProseEditorField is using extensions without sanitization. "
|
|
213
|
+
"For security, it's recommended to enable sanitization with "
|
|
214
|
+
"sanitize=True when using extensions."
|
|
215
|
+
)
|
|
216
|
+
hint = (
|
|
217
|
+
"Add sanitize=True to this field definition for proper HTML sanitization "
|
|
218
|
+
"that matches your configured extensions."
|
|
219
|
+
)
|
|
220
|
+
else:
|
|
221
|
+
message = (
|
|
222
|
+
"This ProseEditorField doesn't have sanitization enabled. "
|
|
223
|
+
"For security, it's recommended to enable sanitization."
|
|
224
|
+
)
|
|
225
|
+
hint = (
|
|
226
|
+
"Consider using the newer extensions mechanism with sanitize=True "
|
|
227
|
+
"for proper HTML sanitization that matches your editor capabilities."
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
warnings.append(
|
|
231
|
+
Warning(
|
|
232
|
+
message,
|
|
233
|
+
hint=hint,
|
|
234
|
+
obj=f"{model._meta.label}.{field.name}",
|
|
235
|
+
id="django_prose_editor.W004",
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return warnings
|