Skip to main content

A model agnostic Django newsletter app integrating Mosaico.

Project description

# Nuntius

Nuntius is a newsletter application for Django.

Nuntius integrates with your Django project.
It is very agnostic about your subscribers and subscriber lists models.

It features [Mosaico](https://mosaico.io/), a drag-and-drop email
editor, for sending beautiful emails to your subscribers.

## How it works

Nuntius is agnostic about your subscribers model. You can use your current
use model, as long as it implements a few required methods.

To allow your end-users to choose recipients, it is your choice to implement
one or more "segment" models. Segment models implement a required method
`get_subscribers_queryset`.

You can then create campaigns in the Django admin panel, and send them to
existing segments.

Celery is used to queue and send emails. Nuntius must have its own celery worker.

## Installation

1. Add "nuntius" to your INSTALLED_APPS setting like this:
````python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
...
'nuntius',
]
````
2. Include Nuntius urlconf in your project `urls.py` like this:
````python
path('nuntius/', include('nuntius.urls')),
````
3. Edit or create your subscriber model so it works with Nuntius.
You must implement all the method from `nuntius.models.BaseSubscriber`.
An easy way to do this is to extend `BaseSubscriber` and to have a
`subscriber_status` `IntegerField` and an `email` `EmailField`, but
you can implement the methods the way you want.

Here is the `BaseSubscriber` code as documentation :

````python
# nuntius.models.BaseSubscriber

class BaseSubscriber:
STATUS_SUBSCRIBED = 1
STATUS_UNSUBSCRIBED = 2
STATUS_BOUNCED = 3
STATUS_COMPLAINED = 4
STATUS_CHOICES = (
(STATUS_SUBSCRIBED, _("Subscribed")),
(STATUS_UNSUBSCRIBED, _("Unsubscribed")),
(STATUS_BOUNCED, _("Bounced")),
(STATUS_COMPLAINED, _("Complained"))
)

def get_subscriber_status(self):
if hasattr(self, 'subscriber_status'):
return self.subscriber_status
raise NotImplementedError()

def get_subscriber_email(self):
if hasattr(self, 'email'):
return self.email

raise NotImplementedError()

def get_subscriber_data(self):
return {
'email': self.email
}
````

Here is an example of a subscriber model you can implement :

````python
# myapp.models.MySubscriberModel
from nuntius.models import BaseSubscriber
from django.db import models
from django.db.models import fields

class MySubscriberModel(BaseSubscriber, models.Model):
email = fields.EmailField(max_length=255)
subscriber_status = fields.IntegerField(choices=BaseSubscriber.STATUS_CHOICES)

4. Set the two required settings in your `settings.py`
````python
NUNTIUS_SUBSCRIBER_MODEL = 'myapp.MySubscriberModel'
NUNTIUS_CELERY_BROKER_URL = 'redis://'
````

5. Launch Redis and celery in the background. In production, you should probably use systemd for this.
The command for celery should be something like this :
```python
export DJANGO_SETTINGS_MODULE=myapp.settings
celery -A nuntius.celery worker
```

Unless you are using a custom admin site, admin panels for Nuntius will be
[autodiscovered](https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#discovery-of-admin-files)
and added to you admin site.

## Advanced usage

If you want to have more control on your recipients, you can create
segment models.

One example of segment is a simple model which holds a Many-to-Many relation
to subscribers. In this case, the segment can be considered as a list.

Another example is a segment model which filters subscribers depending on
the date of their last login :

```python
from django.db import models
from django.db.models import fields
from datetime import datetime

from nuntius.models import BaseSegment


class LastLoginDateSegment(BaseSegment, models.Model):
last_login_duration = fields.DurationField()

def get_display_name(self):
return f'Last login : {str(datetime.now() - self.last_login_duration)}'

def get_subscribers_queryset(self):
return MySubscriberClass.objects.filter(last_login__gt=datetime.now() - self.last_login_duration)

def get_subscribers_count(self):
return MySubscriberClass.objects.filter(last_login__gt=datetime.now() - self.last_login_duration, subscribed=True)

```

* `get_subscribers_queryset` is allowed to return subscribers regardless of their
`subscriber_status`, as `get_subscriber_status` will be called on each instance.
* `get_subscribers_count` is only there for convenience in the admin panel, it does not
have to be accurate. If you want to have it accurate, you should however take
your subscribers status into account.

## License

Copyright is owned by Guillaume Royer and Arthur Cheysson.

You can use Nuntius under GPLv3 terms.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
nuntius-0.1.1-py3-none-any.whl (2.6 MB) Copy SHA256 hash SHA256 Wheel py3
nuntius-0.1.1.tar.gz (2.6 MB) Copy SHA256 hash SHA256 Source None

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page