Skip to main content

Django delayed notifications

This application sends notifications to the user and emails addresses. It stores messages into a database, and sends can be delayed through a cron task.

Installation

$ pip install django-delayed-notifications

Add django_notifications to your INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    "django_notifications",
    ...
)

Apply the migrations:

$ ./manage.py migrate

Usage

Instead of sending a raw email, with the send_mail django function, you can create a Notification object and program the sending.

Notification creation

from pathlib import Path
from django_notifications.models import Notification, Attachment
from django.core.files import File
from django.utils.timezone import now
from datetime import timedelta

# **Basic creation**
my_instance = "<A random object in the application>"
notification = Notification.objects.create(
    subject="My beautiful email",
    text_body="My text body",
    html_body="""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="x-apple-disable-message-reformatting">
    <title>My beautiful email</title>
</head>
<body>My HTML body</body>
</html>
    """,
    from_email="foo@example.org",  # Optional
    related_object=my_instance,  # Optional
)

# ** Related objects states management **
# When using FSM, you can provide the states from / to (Optional)
notification.state_from = "active"
notification.state_to = "processing"

# **Attachments management**
# Include file from a raw file
from django.core.files.base import ContentFile

_attachment = Attachment.objects.create(
    notification=notification,
    attachment_file=ContentFile(Path("<my_file>").open("r"), name="my_file.txt")
)

# Including an attachment from a FileField
from django.db.models.fields import FieldFile

assert isinstance(my_instance.file, FieldFile)

_attachment = Attachment.objects.create(
    notification=notification,
    attachment_file=ContentFile(my_instance.file.read(), name=my_instance.file.name)
)

# **Recipients management**
# You can provide users
notification.recipients.set("<User instance>", "<User instance>", ...)

# And / Or provides email address, `\n` separated
notification.email_recipients = "\n".join([
    "foo@example.org", "bar@example.org"
])
notification.save()

# You can set the delayed sending date
notification.delayed_sending_at = now() + timedelta(days=1)
notification.save()

# Or you can send the email immediately
notification.send()

Notifiers

The app provides a NotifierBase class as helper to create notifications transparently. This class inherit from DetailView, so the email can be previewed, and provides 2 additional public functions :

  • NotifierBase.notify(recipients, email_recipients) -> Send the email right now, in the same process
  • NotifierBase.program(send_at, recipients, email_recipients) -> Program the email send at the send_at datetime.

Usage

First, you have to implement a Notifier from the NotifierBase.

# notifiers.py
from typing import Any

from django.db.models import QuerySet
from django_notifications import NotifierBase

from app import models

class ItemNotifier(NotifierBase):
    """Notifier"""
    # Template for both the email and the HTML
    template_name = "app/notifications/item-email.html"

    # Required to allow the DetailView to work
    def get_queryset(self) -> QuerySet[Any]:
        return models.Item.objects.all()

The ItemNotifier class can be used as a view

# urls.py

from app import notifiers
from django.urls import path

urlpatterns = [
    ...
    path("notification/item/<int:pk>/preview/"), notifiers.ItemNotifier.as_view(), "email-preview"),
    ...
]

When previewing the email content, you can add the text query parameter to see the text email content.

Example:

  • http://localhost:8000/notification/item/1/preview/ displays the HTML content of the email
  • http://localhost:8000/notification/item/1/preview/?text displays the TEXT content of the email

This is useful for debugging email templates, and easily provides a "Read on the website" link in the email.

The ItemNotifier can be used as a ...notifier

from datetime import datetime, timedelta
from django.contrib.auth.models import User

from app import notifiers, models

item = models.Item.objects.get(pk=1)

_notifier = notifiers.ItemNotifier(instance=item) # Bind the notifier to a model instance

# You can set `email_recipients` param for raw email addresses,
# or `recipients` for User model instances. Both can be provided.

_user = User.objects.get(pk=1)
# Immediate send
_notifier.notify(
    email_recipients=["foo@example.com"],
    recipients=_user,
)

# Delayed send
_notifier.program(
    send_at=datetime.now() + timedelta(days=7),
    email_recipients=["foo@example.com"],
    recipients=_user,
)

Management command

Send notifications

This command can be used in a cron, to provide delayed sending.

$ ./manage.py send_notifications --help
usage: manage.py send_notifications [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]

options:
  -h, --help            show this help message and exit
  --version             Show program's version number and exit.
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Display a full stack trace on CommandError exceptions.
  --no-color            Don't colorize the command output.
  --force-color         Force colorization of the command output.
  --skip-checks         Skip system checks.

$ ./manage.py send_notifications
12 notifications sent.

Clean notifications

It's possible to clean attachments and notification (files are removed for storage too)

$ ./manage.py clean_notifications --help
usage: manage.py clean_notifications [-h] [--dry-run] [--days DAYS] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks]

Remove older notifications.

options:
  -h, --help            show this help message and exit
  --dry-run, -n         Do not perform deletions
  --days DAYS, -d DAYS  Delete notifications older already sent since <days> days.
  --version             Show program's version number and exit.
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Display a full stack trace on CommandError exceptions.
  --no-color            Don't colorize the command output.
  --force-color         Force colorization of the command output.
  --skip-checks         Skip system checks.

$ ./manage.py clean_notifications -d 30
20 notifications and 10 attachments are about to be deleted.
20 notifications and 10 attachments are DELETED.

Templates

The application provides some basic templates for emails, and provides some basic blocks.

Provided blocks

{% extends "django_notifications/base_email.html" %
{% block extrahead %}<!-- JS / CSS to add to header -->{% endblock extrahead %}
{% block header %}<!-- Email header (empty) -->{% endblock header %}
{% block page_title %}
{% block title-content %}{{ subject }}{% endblock title-content %}
{% endblock page_title %}
{% block main-content %}<!-- Main content on the email -->{% endblock main-content %}
{% block buttons %}
<div class="buttons">
    {% block buttons-content %}<!-- Link buttons --> {% endblock buttons-content %}
</div>
{% endblock buttons %}
{% block signature %}
<div class="signature">
    {% block signature-content %}<!-- Email signature content --> {% endblock signature-content %}
</div>
{% endblock signature %}

Notifier

THe application provides a helper class to create Notifier. A notifier is a DetailView (can be bound to an URL), et ann the notify(email_recipients, recipients) method which actually send the email.

import logging
from django_notifications import NotifierBase

logger = logging.getLogger(__name__)


class ModelNotifier(NotifierBase):
    """Notifier for the model."""

    template_name = "<app_name>/notifications/instance.html"  # Will be used to render the email AND the view
    subject = "Hello, world!"
    signature = """<address>....</address>"""
    application_name = "Application name"


_instance = ...
_user = ...

_notifier = ModelNotifier(instance=_instance)
sent = _notifier.notify(recipients=_user)

Note

It is possible to call the View with appending the ?text parameter to the query string to view the text email body.

Config

This application provides an admin interface for notifications.

  • delay_notifications: Delay notification sending, using the cron job
  • delay: Delay to apply to notifications
  • receive_notifications_field: Name of the field to allow notification send
  • receive_messages_field: Name of the field to allow notification send -- NOT USED
  • enable_debug_notifications: Enable (re)sending emails
  • debug_notifications_email: Target recipient of the email debugging

Notes

The application is available in English and translated to French.

Metadata

Release files for django-delayed-notifications 0.16.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-delayed-notifications 0.16.1
File Size Uploaded
django_delayed_notifications-0.16.1.tar.gz 28.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-delayed-notifications 0.16.1
File Interpreter ABI Platform
django_delayed_notifications-0.16.1-py3-none-any.whl Python 3 none any Details

Total release size: 77.5 kB

Release files / django_delayed_notifications-0.16.1.tar.gz

Download URL django_delayed_notifications-0.16.1.tar.gz
Size 28.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b741babb037d41d73b96770749e5e14c92c11ecc59b2d44839b2023ae34aa2e4
BLAKE2b-256 checksum
How to use checksums
84550983c2be7e362a5e3d547b7aacc88dd03952226c8547dcf7032bf8991333
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / django_delayed_notifications-0.16.1-py3-none-any.whl

Download URL django_delayed_notifications-0.16.1-py3-none-any.whl
Size 48.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b22f9213c62179fcf0ff4f9a7af8840cc9c6bf5863255dd65ead8beb36732cd1
BLAKE2b-256 checksum
How to use checksums
0efa0e100ddfc300b913a95350536722723c05b8cb71d1fad100330f60095d40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","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.16.1 This release

2 release files

0.16.0

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.3

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.3

2 release files

0.12.2

2 release files

0.12.1

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.6.19

2 release files

0.6.18

2 release files

0.6.16

2 release files

0.6.14

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