Newsletters¶
The newsletter system allows composing newsletters from templates and scheduling them for delivery.
Newsletter Templates¶
Newsletter templates provide reusable HTML content structures. They can optionally reference a model base for dynamic content.
from djgentelella.async_notification.models import NewsLetterTemplate
NewsLetterTemplate.objects.create(
title='Monthly Digest',
slug='monthly-digest',
message=(
'<h1>Monthly Digest</h1>'
'<p>Here are the highlights from this month.</p>'
),
model_base='customers', # Key from ASYNC_NEWS_BASE_MODELS
)
Creating Newsletters¶
A newsletter is composed from a template with specific recipients:
from djgentelella.async_notification.models import (
NewsLetterTemplate, NewsLetter
)
template = NewsLetterTemplate.objects.get(slug='monthly-digest')
newsletter = NewsLetter.objects.create(
template=template,
subject='January 2026 Monthly Digest',
message=template.message, # Or customized content
recipients='subscribers@group.local, vip@group.local',
created_by=user,
)
Recipients support the same resolver syntax as email notifications (see Recipient Resolvers).
Scheduling Newsletter Tasks¶
Newsletter delivery is controlled through NewsLetterTask objects:
from django.utils import timezone
from djgentelella.async_notification.models import NewsLetterTask
task = NewsLetterTask.objects.create(
newsletter=newsletter,
send_date=timezone.now() + timezone.timedelta(days=7),
)
Task lifecycle:
Task is created with
status='pending'.The backend
schedule()method is called (either Celery beat or cron-based).When
send_datearrives, the task is picked up andstatustransitions tosending.After successful delivery,
statusbecomessent.On failure,
statusbecomesfailed.
Revoking a task:
Tasks with pending or scheduled status can be revoked:
from djgentelella.async_notification.backends import get_backend
backend = get_backend()
backend.revoke(task.pk)
# Task status is now 'revoked'
Custom SMTP for Newsletters¶
Newsletters can use a separate SMTP server from regular notifications. Configure it in settings:
ASYNC_NEWSLETTER_SEVER_CONFIGS = {
'host': 'smtp.newsletter-provider.com',
'port': 587,
'username': 'newsletters@example.com',
'password': 'secret',
'use_tls': True,
}
If not configured, newsletters use Django’s default email backend.
File Attachments¶
Newsletters support a single file attachment via the attached_file field:
newsletter = NewsLetter.objects.create(
template=template,
subject='Product Catalog',
message='<p>Please find our latest catalog attached.</p>',
recipients='subscribers@group.local',
attached_file=uploaded_file,
created_by=user,
)
Preview Recipients¶
The management UI provides a “Preview Recipients” action that resolves all recipient addresses without sending any email. This is useful for verifying that group resolvers and email addresses are configured correctly before scheduling a send.
The API endpoint is a GET request to /objapi/newsletter/<id>/preview_recipients/,
which returns a JSON response with the resolved email list and count.