HTML, choices and tags
HTMLField​
A text field for HTML content. Content is sanitized on save, so every value stored through the field is clean — no matter how the instance gets saved.
from blueprint.fields import HTMLField
class Article(models.Model):
body = HTMLField()
article = Article(body="<p>Hi</p><script>alert(1)</script>")
article.save()
article.body # "<p>Hi</p>"
The default sanitizer​
The built-in sanitizer (blueprint.sanitizers.sanitize_html, powered by
nh3) keeps a CMS-friendly allowlist of tags
(headings, text, lists, links, images, tables, audio/video) and safe
attributes (class, href, src, alt, title, sizes, and a few more),
allows only the http, https, mailto and tel URL schemes, adds
rel="noopener noreferrer" to links, and strips comments and everything
else — including the content of script and style tags.
Customizing the sanitizer​
Two levels of customization, both resolved lazily:
Project-wide — set BLUEPRINT["HTML_SANITIZER"] in your Django settings
to a callable or a dotted import path:
# settings.py
BLUEPRINT = {
"HTML_SANITIZER": "myapp.text.sanitize",
}
Per field — pass sanitizer to an individual field; it wins over the
project-wide setting. Use a module-level function (not a lambda), because
the sanitizer is serialized into your migrations:
from blueprint.fields import HTMLField
class Article(models.Model):
# myapp.text.sanitize_upper is a module-level function
body = HTMLField(sanitizer="myapp.text.sanitize_upper")
To opt out of sanitizing entirely — for example when you sanitize on input through your editor — point the sanitizer at a passthrough function:
def passthrough(value):
return value
BLUEPRINT = {"HTML_SANITIZER": passthrough}
MultipleChoiceField​
A JSON array field with a fixed set of allowed values. Options can be passed as a mapping or an iterable of pairs; values outside the options are rejected by the field's validator.
from blueprint.fields import MultipleChoiceField
class Page(models.Model):
sections = MultipleChoiceField(
options={"hero": "Hero", "grid": "Grid", "cta": "Call to action"}
)
page = Page(sections=["hero", "grid"]) # valid
page = Page(sections=["hero", "oops"]) # ValidationError
Defaults to an empty list and blank=True. The options are part of the
field's serialized form, so changing them produces a migration.
TagField​
A JSON array field for tags. Any string is a valid tag — the field has no opinion on their shape. On save it trims surrounding whitespace and drops duplicates and tags that end up empty.
from blueprint.fields import TagField
class Article(models.Model):
tags = TagField()
article = Article(tags=["Django", " web dev ", "Django", " "])
article.save()
article.tags # ["Django", "web dev"]
Defaults to an empty list and blank=True.
HashTagField​
A JSON array field for hashtags, built on TagField. Values are normalized
to hashtag form on save: lowercased, all whitespace and # signs removed,
duplicates dropped and empty results discarded.
from blueprint.fields import HashTagField
class Article(models.Model):
hashtags = HashTagField()
article = Article(hashtags=["#DjangoCon", " New York ", "djangocon"])
article.save()
article.hashtags # ["djangocon", "newyork"]
Defaults to an empty list and blank=True.