django-post-office

raw JSON →
3.11.2 verified Mon Apr 27 auth: no python

A Django app to monitor and send mail asynchronously, complete with template support. Current version 3.11.2, released Feb 2026. Release cadence is irregular, roughly 2-4 minor versions per year.

pip install django-post-office
error ModuleNotFoundError: No module named 'post_office'
cause Package not installed or not added to INSTALLED_APPS.
fix
Run pip install django-post-office and add 'post_office' to INSTALLED_APPS in settings.py.
error django.core.exceptions.ImproperlyConfigured: Requested setting POST_OFFICE, but settings are not configured.
cause Using post_office outside of Django's setup, e.g., in a standalone script without calling django.setup().
fix
Call django.setup() after setting the DJANGO_SETTINGS_MODULE environment variable.
error AttributeError: module 'post_office' has no attribute 'send_mail'
cause Incorrect function name; the correct function is `mail.send()`.
fix
Use from post_office import mail; mail.send(...).
breaking In v3.11.0, the dependency `bleach` was replaced with `nh3` for HTML sanitization. If you rely on `bleach` directly or indirectly, update your code.
fix Ensure `nh3` is installed, and remove any direct use of `bleach` in post_office contexts.
breaking In v3.7.0, JSON columns were changed from third-party `jsonfield` to Django's native `JSONField`. If you have custom migrations that depend on `jsonfield`, they will break.
fix Run `makemigrations` to regenerate migrations after upgrading. Remove any explicit dependency on `jsonfield`.
deprecated The `date_hierarchy` option was removed in v3.7.1 from the Email admin, causing slow loading on large databases. If you rely on date-based drilldown in admin, implement custom admin filters.
fix Do not rely on `date_hierarchy`. Use list_filters or custom filters instead.
gotcha When using `mail.send` with a template, context must include all variables needed, but if the template is missing or invalid, the email fails silently. Always check the backend logs.
fix Use `template='your_template'` and pass context as a dict. Test with `priority='now'` to see errors immediately.

Send an email immediately using django-post-office.

import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')
django.setup()
from post_office import mail
mail.send(
    recipients=['user@example.com'],
    sender='from@example.com',
    subject='Test email',
    message='Hello, World!',
    priority='now'
)