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 processNotifierBase.program(send_at, recipients, email_recipients)-> Program the email send at thesend_atdatetime.
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 emailhttp://localhost:8000/notification/item/1/preview/?textdisplays 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.0
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_delayed_notifications-0.16.0.tar.gz | 28.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_delayed_notifications-0.16.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.5 kB
Release files / django_delayed_notifications-0.16.0.tar.gz
| Download URL | django_delayed_notifications-0.16.0.tar.gz |
|---|---|
| Size | 28.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4a2f0632f20b440638ff76844778909803b743c8a610f7e06001be8dd80f5d5
|
|
BLAKE2b-256 checksum How to use checksums |
1c7dd1b9423565e0b4e925df67f8a0dda99fa2e43e8eff0bb5344a93d3781ce1
|
| 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.0-py3-none-any.whl
| Download URL | django_delayed_notifications-0.16.0-py3-none-any.whl |
|---|---|
| Size | 48.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e1a2ace668de32496096267e0605ba2f3765dfa601dabeed28839d0ef5820b2c
|
|
BLAKE2b-256 checksum How to use checksums |
5ca2592524b09fb0e4f9e36a362d56779c74fc61f560c5a87cb04206b4f13979
|
| 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}
|