Skip to main content
Latest Version CI Status

A Django middleware that converts HTML responses to Markdown when the client sends an Accept: text/markdown request header.

Requirements

django-markdown-middleware supports Python 3.11+ and requires Django 5.2 or later.

Installation

$ pip install django-markdown-middleware

Add the middleware to your Django settings:

MIDDLEWARE = [
    ...
    "markdown_middleware.middleware.MarkdownMiddleware",
    ...
]

The middleware must be placed after any middleware that sets the response content type (e.g. after CommonMiddleware).

Usage

Any client that sends Accept: text/markdown in the request headers will receive the HTML response body converted to Markdown, with the response Content-Type changed to text/markdown; charset=utf-8.

The response also includes an X-Markdown-Tokens header containing an approximate token count of the converted Markdown content (estimated as len(markdown) // 4).

Only HTTP 200 responses with a text/html content type are converted. All other responses are passed through unchanged.

Caching

To enable caching of converted Markdown responses, set MARKDOWN_MIDDLEWARE_CACHE_TIMEOUT in your Django settings to the desired cache duration in seconds:

# Cache converted Markdown responses for 5 minutes
MARKDOWN_MIDDLEWARE_CACHE_TIMEOUT = 300

When this setting is absent or None, no caching is performed.

Cache keys have the form markdown_middleware:<path>, for example markdown_middleware:/api/products/, making them easy to inspect or manage directly in your cache backend.

Cache Invalidation

To invalidate cached Markdown responses for a specific path, use invalidate_cache. It removes all cached variants of that path, including responses with different query strings:

from markdown_middleware import invalidate_cache

# Invalidates /blog/my-post/, /blog/my-post/?page=2, etc.
invalidate_cache("/blog/my-post/")

This is useful in post-save signals or management commands when content changes and the cached Markdown must be refreshed.

Configuration

Set MARKDOWN_MIDDLEWARE_ANONYMOUS_ONLY to False to also convert responses for authenticated users (defaults to True):

MARKDOWN_MIDDLEWARE_ANONYMOUS_ONLY = False

Set MARKDOWN_MIDDLEWARE_CACHE_TIMEOUT to the desired cache duration in seconds for converted Markdown responses. When absent or None (the default), no caching is performed:

MARKDOWN_MIDDLEWARE_CACHE_TIMEOUT = 300

Set MARKDOWN_MIDDLEWARE_CONVERT_OPTIONS to a dictionary of keyword arguments passed directly to html-to-markdown’s ConversionOptions. When absent or None (the default), the library’s defaults are used.

Remove inline SVG elements:

MARKDOWN_MIDDLEWARE_CONVERT_OPTIONS = {"strip_tags": ["svg"]}

Remove inline (data URI) images while keeping linked images:

MARKDOWN_MIDDLEWARE_CONVERT_OPTIONS = {"exclude_selectors": ['img[src^="data:"]']}

Both options combined:

MARKDOWN_MIDDLEWARE_CONVERT_OPTIONS = {
    "strip_tags": ["svg"],
    "exclude_selectors": ['img[src^="data:"]'],
}

See the html-to-markdown documentation for the full list of available options.

Prepare for development

Install uv, then:

$ uv sync --group dev

Run the tests:

$ make tests

Metadata

Release files for django-markdown-middleware 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-markdown-middleware 0.3.1
File Size Uploaded
django_markdown_middleware-0.3.1.tar.gz 54.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-markdown-middleware 0.3.1
File Interpreter ABI Platform
django_markdown_middleware-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 60.8 kB

Release files / django_markdown_middleware-0.3.1.tar.gz

Download URL django_markdown_middleware-0.3.1.tar.gz
Size 54.7 kB
Tags Source
SHA-256 checksum
How to use checksums
0eb79ffa82c64652e747394bc9206c573e39751cb2564a36f8a544a88afc4f49
BLAKE2b-256 checksum
How to use checksums
a095af06eb3cfe6ea29557efcaa7238361d911e6e77e045d72be0a51777d99b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / django_markdown_middleware-0.3.1-py3-none-any.whl

Download URL django_markdown_middleware-0.3.1-py3-none-any.whl
Size 6.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
36b968200a827c3a8dc32fbe24db622142a37053c805ed31d0b27ad434c98cb7
BLAKE2b-256 checksum
How to use checksums
ffa758d1b848818c85d657d4d9ca74c04e6310632c6164dcbbd71c56a162554f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

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