Skip to main content

A simple custom field for Django that can safely render Markdown and store it in the database.

Project description

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.

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.

Project details


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.18.0.tar.gz (810.6 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.18.0-py3-none-any.whl (767.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_markdownfield-0.18.0.tar.gz
  • Upload date:
  • Size: 810.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_markdownfield-0.18.0.tar.gz
Algorithm Hash digest
SHA256 488639c47905640f98a7e44fdae6dbdff44125b7af01f9e217ce14faac23652d
MD5 65aae36640f215c221d7580d17ef5fe5
BLAKE2b-256 e20b7b59070e77635ea156007b421a8cae28e0629cba368ba95cf10c56180fb2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for django_markdownfield-0.18.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd9b16215aa95cf9fc4dad3228a71267774c07434180516d4a6b318f6e0e6fef
MD5 b89259027e99cb943f0787d05b8ea15d
BLAKE2b-256 b75c271d2c81f1d560946c75eda10992c9a66194e5abcd5c51efe27f74610444

See more details on using hashes here.

Provenance

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page