diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 0dd255f..b306703 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -5,6 +5,10 @@ Next version
~~~~~~~~~~~~
- Allowed installing the package in Python 3.10 environments too.
+- Tweaked the cleaning methods of ``ProseEditorField`` and
+ ``SanitizedProseEditorField`` to produce empty strings when no content is
+ entered. Previously they would produce an empty paragraph (``
``) since
+ our ProseMirror schema says that there exists always one or more block nodes.
0.3 (2024-04-09)
diff --git a/django_prose_editor/fields.py b/django_prose_editor/fields.py
index 35fcd1c..e83a3cf 100644
--- a/django_prose_editor/fields.py
+++ b/django_prose_editor/fields.py
@@ -1,3 +1,5 @@
+import re
+
from django import forms
from django.db import models
from django.utils.html import strip_tags
@@ -6,13 +8,21 @@
from django_prose_editor.widgets import ProseEditorWidget
-def _identity(x):
+def _actually_empty(x):
+ """
+ ProseMirror's schema always adds at least one empty paragraph
+
+ We want empty fields to actually be empty strings so that those field
+ values evaluate as ``False`` in a boolean context.
+ """
+ if re.match(r"^<(?P\w+)>(?P=tag)>$", x):
+ return ""
return x
class ProseEditorField(models.TextField):
def __init__(self, *args, **kwargs):
- self.sanitize = kwargs.pop("sanitize", _identity)
+ self.sanitize = kwargs.pop("sanitize", _actually_empty)
self.config = kwargs.pop("config", {})
super().__init__(*args, **kwargs)
diff --git a/django_prose_editor/sanitized.py b/django_prose_editor/sanitized.py
index 1e0a81e..52fedce 100644
--- a/django_prose_editor/sanitized.py
+++ b/django_prose_editor/sanitized.py
@@ -1,10 +1,14 @@
-from django_prose_editor.fields import ProseEditorField
+from django_prose_editor.fields import ProseEditorField, _actually_empty
+
+
+def _nh3_sanitizer():
+ from nh3 import clean
+
+ return lambda x: _actually_empty(clean(x))
class SanitizedProseEditorField(ProseEditorField):
def __init__(self, *args, **kwargs):
if "sanitize" not in kwargs:
- from nh3 import clean
-
- kwargs["sanitize"] = clean
+ kwargs["sanitize"] = _nh3_sanitizer()
super().__init__(*args, **kwargs)
diff --git a/tests/testapp/test_prose_editor.py b/tests/testapp/test_prose_editor.py
index a8b30fa..afcfc0c 100644
--- a/tests/testapp/test_prose_editor.py
+++ b/tests/testapp/test_prose_editor.py
@@ -2,12 +2,33 @@
from django.db import models
from django.test.utils import isolate_apps
+from django_prose_editor.fields import ProseEditorField
from django_prose_editor.sanitized import SanitizedProseEditorField
class Test(test.TestCase):
@isolate_apps()
- def test_field(self):
+ def test_standard_field(self):
+ class Model(models.Model):
+ description = ProseEditorField()
+
+ def __str__(self):
+ return self.description
+
+ m = Model(description="")
+ m.full_clean()
+ self.assertEqual(m.description, "")
+
+ m = Model(description="")
+ m.full_clean()
+ self.assertEqual(m.description, "")
+
+ m = Model(description="hello
")
+ m.full_clean()
+ self.assertEqual(m.description, "hello
")
+
+ @isolate_apps()
+ def test_sanitized_field(self):
class Model(models.Model):
description = SanitizedProseEditorField()
@@ -17,3 +38,15 @@ def __str__(self):
m = Model(description="Hello
")
m.full_clean()
self.assertEqual(m.description, "Hello
")
+
+ m = Model(description="")
+ m.full_clean()
+ self.assertEqual(m.description, "")
+
+ m = Model(description="")
+ m.full_clean()
+ self.assertEqual(m.description, "")
+
+ m = Model(description="hello
")
+ m.full_clean()
+ self.assertEqual(m.description, "hello
")