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)
| File | Size | Uploaded | |
|---|---|---|---|
| django_markdown_middleware-0.3.1.tar.gz | 54.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|