📜 ⬆️ ⬇️

Django DB Mailer is a simple and convenient battery for sending email messages in your project.

In the overwhelming majority of projects, sending messages to the postal addresses of clients / administrators / departments is used. How tedious it is to create templates on the file system each time, set signals, use frequently duplicated code for rendering and sending.

In the end, there are the tasks of background sending, sender changes, prioritization, resubmitting a message in case of failure, frequent editing at the request of the client / marketers, attaching standard files to the letter in the form of some instructions for using the product, or standard documents, reports on customers, transfers, etc. and etc.

In large projects, it is often necessary to visually divide templates into categories, to filter, so as not to waste time editing less important templates when refactoring, and to avoid confusion with new content, or when working with old ones.
')
For such solutions, there is a simple battery, designed to solve most of these problems, and save you from unnecessary code, maintenance and hassle.



django-db-mailer is an open and easy-to-use battery for sending email messages, mailings and deferred notifications. Does not require special knowledge or non-standard settings. All you have to do is install the package, set up the Celery queue system in conjunction with Redis , and you can start doing creative work.

What can a battery out of the box?


1. Simple and convenient functional interface for sending emails.
2. Work in the specified queue (it is necessary when everything is divided into different servers and workers in the project).
3. The ability to re-send a message in case of failure (there is an opportunity to set the number of attempts in the database and in the code).
4. Timeouts
5. Logging (you can always see which message was sent successfully / unsuccessfully. Useful when investigating complaints from users).
6. Categories (fast filtering of heterogeneous templates. Cataloging by app, etc. and etc.).
7. Recipient groups (convenient for division into departments within the company and setting recipient addresses in the admin panel).
8. Signals (sending messages for the post_save / pre_save & etc. event is configured directly in the admin panel).
9. Delayed sending messages (good for all sorts of promo, as well as when using transactions in the views).
10. Built-in browser fields in the models (no need to go into the code to view the available fields for use. Do not drag you, and you do not climb into the code).
11. Prioritization system (the ability to set the priority of the message in the database / code).
12. Editing templates directly in the admin (for support, managers - the most it, does not take the time of the programmer).
13. Templates are cached - every time a message is sent there is no access to the database (the templates and settings are read from the cache, which reduces the load on the database. The backend is for your taste).
14. TinyMCE / CKEditor visual editor (optional).
15. Versioning changes in templates. You can always roll back (there are times when you can't do without it).
16. Localization of batteries / English.
17. Testing messages directly from the admin panel (it is possible to create a template and immediately get an example to the current user's mailbox).
18. The popular django-grappelli theme is supported out of the box.
19. Types of letters html and text (the ability to specify the type of template).
20. Ability to use all the built-in capabilities of the mailer jung.
21. Bcc - it is possible to duplicate all letters to the specified addresses (it is useful for logging with text. By default, the letter body is not logged into the database for security reasons).
22. API - to work with applications in other languages ​​/ platforms.
23. The ability to set the “From” field to each template (useful when you have several departments. Especially convenient when transferring responsibilities to another department).
24. SMTP settings for recipients (you can configure different smtp servers to send letters).
25. Attaching standard files (various inserts, documents, instructions right in the admin).
26. Multilingual templates for localized sites (one template for multilingual sites. Depending on the locale, the language of the message is selected).
27. Disable / Enable alerts (convenient for debugging, or for temporarily disabling some company promotions).
28. Simple integration with popular services such as postmark / aws ses (just install python-postmark / django-ses).
29. Catching and sorting by Python exceptions (in the case of using a post-mark, or something else, it is convenient to filter and quickly solve the problem).
30. View the differences between versions (you always need to see who and what changed in the templates, and what is the cause of the error).
31. Reporting on the letters read by users (including information about geo. But there are no guarantees here).
32. Sending SMS (all features of mailer are also available for SMS notifications).
33. Text to speech (convenient for people with disabilities, or for urgent notifications through calls).
34. Push notifications (for mobile applications, via BaaS - parse.com, including Prowl for administrators).
35. Empowering the battery through the use of its own backends and providers.
36. Updating templates in real time (no need to create files, commit, and roll out updates on servers).
37. Basic templates (you can easily inherit, and change them at any convenient time).
38. Signals pre_send / post_send (for example, it is necessary in the case of sending paid sms, for counting the number of characters and fixing in the billing)
39. Subscriptions (by default there is a subscription implementation, with the possibility of mailings / notifications, etc., including preferences for the notification time)

The capabilities of the battery are closely related to Celery and Redis . More precisely - it is a background send, queue, priorities, and delayed send.

Although most of the functionality works without them. That is, you can use the battery and without any external dependencies.

This is at the discretion of the programmer. Difficulties in setting up those or other parts - no problem. There is detailed documentation.

Instead of Redis, you can use RabbitMQ, MongoDB and all supported backers for Celery.
Unfortunately, in Celery priorities are implemented only for Redis. At the heart of quasi-priorities (not on the server side).

Let's look at a simple example for sending a message :

from dbmail import send_db_mail #   settings = Settings.objects.get(user_id=1) user = User.objects.get(pk=1) data = {'path': request.path} #    send_db_mail('welcome-notification', user.email, settings, user, data) #      send_db_mail('daily-report', user.email, user, data, files=[report_file]) 

In this case, we set the message ID, specify the recipient, and transfer 2 models to the context, which are automatically unpacked in the template + dictionary.

We can refer to the User model fields in the template as username or email. But it also remains possible to contact them in the generally accepted form: user.username.

More detailed example :

  send_db_mail( #     slug='welcome', #      . : # 'user1@example.com'  'user1@example.com, user2@example.com',  # ['user1@example.com', 'user2@example.com'],    #   MailGroup. : developers, support, admins recipient='user1@example.com', #   *args       { 'username': request.user.username, 'full_name': request.user.get_full_name(), 'signup_date': request.user.date_joined }, #     ,      #  . #  m2m  fk,    module_name (mymodel.user.email). MyModel.objects.get(pk=1), #    **kwargs: # from_email='from@example.com' #   # cc=['cc@example.com'], #  (  ,    recipient) # bcc=['bcc@example.com'], #   (  ,    recipient) # user=User.objects.get(pk=1), # ,     # #         Django # attachments=[(filename, content, mimetype)], # files=['hello.jpg', 'world.png'], # headers={'Custom-Header':'Some value'}, # # queue='default', #  # retry_delay=300, #        # max_retries=3, #  -    # retry=True, #     # time_limit=30, #  -    # send_after=60, #    N  # # use_celery=True, #  Celery # #         django.core.mail.message ) 

Installation of the demo project:


  $ sudo apt-get install -y virtualenvwrapper redis-server || brew install pyenv-virtualenvwrapper redis $ source /usr/share/virtualenvwrapper/virtualenvwrapper.sh || source /usr/local/bin/virtualenvwrapper.sh $ mkvirtualenv db-mailer $ workon db-mailer $ git clone --depth 1 https://github.com/LPgenerator/django-db-mailer.git db-mailer $ cd db-mailer $ python setup.py develop $ cd demo $ pip install -r requirements.txt $ python manage.py syncdb --noinput $ python manage.py migrate --noinput $ python manage.py createsuperuser --username admin --email admin@local.host $ python manage.py runserver >& /dev/null & $ python manage.py celeryd -Q default >& /dev/null & 

using docker:

  $ git clone --depth 1 https://github.com/LPgenerator/django-db-mailer.git db-mailer $ cd db-mailer $ docker build -t dbmail . $ docker run -it -d -p 8000:8000 --name dbmail dbmail $ docker exec -i -t dbmail /bin/bash $ cd /mailer/ 

using vagrant:

  $ git clone --depth 1 https://github.com/LPgenerator/django-db-mailer.git db-mailer $ cd db-mailer $ vagrant up $ vagrant ssh $ cd /mailer/ 

Run the shell:

  $ python manage.py shell_plus --print-sql 

Create our first template:

  >>> from dbmail.models import MailTemplate >>> from dbmail import send_db_mail >>> >>> MailTemplate.objects.create( ... name="Site welcome template", ... subject="Welcome", ... message="Welcome to our site. We are glad to see you.", ... slug="welcome", ... is_html=False, ... ) 

Send a letter:

  >>> send_db_mail('welcome', 'user@example.com', use_celery=False) 

For the first time, all queries to the database will be output to the console, as well as the letter itself. The second time requests to the database will be absent. Only requests to write to the log.

Check that we have in the logs:

  >>> from pprint import pprint >>> from django.forms.models import model_to_dict >>> from dbmail.models import MailLog >>> >>> pprint([model_to_dict(obj) for obj in MailLog.objects.all()]) 

Now you can look into the admin area:

  $ xdg-open http://127.0.0.1:8000/admin/dbmail/ >& /dev/null || open http://127.0.0.1:8000/admin/dbmail/ >& /dev/null 

Additional features:


Story
To save the history of changes / rollback, you can install the battery django-reversion .

Editor
In order to edit the templates in the visual editor, you can put the django-tinymce battery .

Topics
django-db-mailer - supports both native theme and django-grappelli .

Queues
To send messages in the background with priority support, you need a django-celery battery .

Multilingual
Multilingualism is possible in conjunction with the django-modeltranslation .

CSS transform
To convert and use inline CSS, you can pre-install the premailer package. A small but useful helper for creating cross-client messages.

Reports
Reading reports and information about user data can be obtained by installing 2 simple httpagentparser and django-ipware batteries .

Basic patterns
By default, there are ready-made basic templates that are optimized for desktop, mobile and browsers. In order to start using them, you only need to import them:
  $ python manage.py load_dbmail_base_templates 

after which you can substitute your variables and blocks for use in letter templates.

Notes
In order for the prioritization to work, a combination of django-celery with the Redis broker is necessary.

Older versions
If you do not need all the functionality, you can use a simpler version of the battery .

You can also use the DB_MAILER_ALLOWED_MODELS_ON_ADMIN variable to disable unnecessary functionality in the admin panel.

API
You can also use the battery in conjunction with a mobile application, or in internal projects in other languages. There are no restrictions. The project in this context is an external addition to absolutely any framework or project in languages ​​other than Python.

A simple example:

  >>> from dbmail.models import ApiKey >>> ApiKey.objects.create(name='Test', api_key='ZzriUzE') 

We try to send an email using curl in the terminal:

  $ curl -X POST http://127.0.0.1:8000/dbmail/api/ --data 'api_key=ZzriUzE&slug=welcome&recipient=root@local.host' 

API 1k + rps bandwidth on a simple i7 2.3GHz

More examples for your programming language can be found in the documentation in the project repository.

Django support from 1.4 to 1.9. Python 2.6, 2.7, pypy, 3.4+, pypy3

Screenshots















This battery is used in several large projects, and saved a lot of time and nerves.
I hope it will be useful to the Django community.

Page on PyPi .
Project repository on GitHub .

Pull Requests are welcome (for those who want to help, TODO.RU is at the root of the project).

Source: https://habr.com/ru/post/253445/


All Articles