Skip to main content

django-markdownfield PyPI

A Django field that renders Markdown to sanitized HTML and stores both in your database.

Your text is stored in a MarkdownField. When the model is saved, django-markdownfield renders it with markdown-it-py (by default), sanitizes it with nh3, and stores the result in a RenderedMarkdownField.

The rendering backend is swappable. Bundles EasyMDE (v2.20.0) for admin and frontend forms.

Editor screenshot

Installation

pip install django-markdownfield

Add to INSTALLED_APPS and configure the rendering backend:

INSTALLED_APPS = [
    'markdownfield',
    ...
    'django.contrib.staticfiles',
]

MARKDOWNFIELD_BACKEND = 'markdownfield.backends.markdownit'

Backend configuration (plugins, HTML passthrough, custom backends) is covered in docs/backends.md. A python-markdown backend is also included (pip install django-markdownfield[pymarkdown]).

To enable the admin preview endpoint, add the URL configuration:

urlpatterns = [
    path('markdownfield/', include('markdownfield.urls')),
    ...
]

Quick start

Add a MarkdownField and a paired RenderedMarkdownField to your model:

from django.db import models

from markdownfield.models import MarkdownField, RenderedMarkdownField
from markdownfield.validators import VALIDATOR_STANDARD

class Page(models.Model):
    text = MarkdownField(rendered_field='text_rendered', validator=VALIDATOR_STANDARD)
    text_rendered = RenderedMarkdownField()

Whenever your model is saved, the RenderedMarkdownField will be updated automatically.

Display in templates

To display the rendered markdown in your template, just display the RenderedMarkdownField like any other field.

{{ page.text_rendered }}

If you don't want to use a RenderedMarkdownField, use the template filter to render raw Markdown in your templates directly:

{% load markdownfield %}

{{ page.text|render_markdown }}
{{ page.text|render_markdown:"classy" }}

The argument is a validator name. Defaults to standard.

Render in Python

from markdownfield.rendering import render_markdown
from markdownfield.validators import VALIDATOR_STANDARD

html = render_markdown('**bold**', VALIDATOR_STANDARD)

Validators

Validators control which HTML tags and attributes survive sanitization, and which toolbar buttons appear in the editor.

Validator Tags Use case
VALIDATOR_STANDARD All standard Markdown tags General content
VALIDATOR_CLASSY Standard + class on links/images, data-* attributes Styled content
VALIDATOR_NO_IMAGES Standard without images User-generated content
VALIDATOR_BASIC Inline only: bold, italic, strikethrough, code, links Comments, bios
VALIDATOR_NULL No sanitization Dangerous. Allows XSS.

Full details + custom validators are covered in docs/validators.md.

Editor

The EasyMDE editor is enabled automatically in admin and frontend ModelForms.

For frontend forms, you will need to include the form media in your template:

<head>
    {{ form.media.css }}
</head>
<body>
    <form method="post">
        {% csrf_token %}
        {{ form }}
        <button type="submit">Save</button>
    </form>
    {{ form.media.js }}
</body>

Disable per-field with use_editor=False (frontend) or use_admin_editor=False (admin).

EasyMDE options can be customized by overriding the widget in your form:

from markdownfield.widgets import MDEWidget

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['text']
        widgets = {
            'text': MDEWidget(options={'toolbar': ['bold', 'italic', 'link']}),
        }

Link processing

These settings control post-sanitization link handling. They apply regardless of which backend is used.

Setting Default Description
MARKDOWNFIELD_MARK_EXTERNAL_LINKS True Add target="_blank" and class="external" to external links.
MARKDOWNFIELD_INTERNAL_URL None Your site's URL or a list of URLs (e.g. 'https://example.com' or ['https://example.com', 'https://cdn.example.com']). Links matching these are treated as internal. Without it, all links are treated as external.
MARKDOWNFIELD_BLOCKED_LINK_DOMAINS [] List of domains whose links are stripped (link text preserved).

Management commands

rerender_markdown - re-renders all stored Markdown into their paired rendered fields. Run after upgrading django-markdownfield, changing validators, or switching backends.

python manage.py rerender_markdown
python manage.py rerender_markdown --dry-run

Further reading

  • Backends - switching backends, python-markdown support, custom backends, plugins
  • Validators - built-in validators, creating custom validators

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_markdownfield-0.21.1.tar.gz (184.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_markdownfield-0.21.1-py3-none-any.whl (138.2 kB view details)

Uploaded Python 3

File details

Details for the file django_markdownfield-0.21.1.tar.gz.

File metadata

  • Download URL: django_markdownfield-0.21.1.tar.gz
  • Upload date:
  • Size: 184.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_markdownfield-0.21.1.tar.gz
Algorithm Hash digest
SHA256 f869a23241aae7a049096c5d05dff522dc3b764bd024f567dac997a08fe2ae54
MD5 fd77d3b9de8a84579e4dcc64b16c47d1
BLAKE2b-256 5bd91b58dfc3f96132674195554ba92e34e0107103a3f30ff956492eec0ab677

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_markdownfield-0.21.1.tar.gz:

Publisher: release.yml on dmptrluke/django-markdownfield

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_markdownfield-0.21.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_markdownfield-0.21.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f665f9957dd48411c3c51f3f041dd51d0d8af8ec48b07190b214e9ddf0144a2d
MD5 32100033d1c2813403c76600f64415dd
BLAKE2b-256 c07381e81e8e96af7d4b4f8e0689c69d9a6ecfe20ce69068eaff439aaaa83f51

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_markdownfield-0.21.1-py3-none-any.whl:

Publisher: release.yml on dmptrluke/django-markdownfield

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.21.1 This release

2 files

0.21.0

2 files

0.20.2

2 files

0.20.0

2 files

0.19.0

2 files

0.18.4

2 files

0.18.1

2 files

0.18.0

2 files

0.17.4

2 files

0.17.3

2 files

0.17.2

2 files

0.17.1

2 files

0.17.0

2 files

0.16.0

2 files

0.15.1

2 files

0.15.0

2 files

0.14.0

2 files

0.13.2

2 files

0.13.1

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.1

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.1

2 files

0.4.0

2 files

0.3.4

1 file

0.3.3

1 file

0.3.2

1 file

0.3.1

1 file

0.3.0

1 file

0.2.13

1 file

0.2.12

1 file

0.2.11

1 file

0.2.10

1 file

0.2.9

1 file

0.2.7

1 file

0.2.6

1 file

0.2.5

1 file

0.2.3

1 file

0.2.2

1 file

0.2.1

1 file

0.2.0

1 file

0.1.1

1 file

0.1.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page