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.0.tar.gz (184.7 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.0-py3-none-any.whl (138.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_markdownfield-0.21.0.tar.gz
  • Upload date:
  • Size: 184.7 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.0.tar.gz
Algorithm Hash digest
SHA256 6f88d0080dee6cdae39a63a82e0f3e21d80269913716781ae7a7533cf4251ac0
MD5 960ebe23999b8e0295e5dfea9fea710c
BLAKE2b-256 a9d34c14f49bad2c445700a71c50b65970cf3d065152546c8bdbe9069ce9a672

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_markdownfield-0.21.0.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.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_markdownfield-0.21.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c0da3e9012582146a5203b94913603e5eceb063b1298a250a25775173e63584b
MD5 6b49ecbf9e46fddb14e77e75ef7fe1a6
BLAKE2b-256 02b65b4bfd6a386e61e6182dd1c88e81a7aeaaf949aec08f5a128716a09b85f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_markdownfield-0.21.0-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

0.21.1

2 files

This release

0.21.0 This release

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