2

I'm looking to speed up loading time for my website by sending my mail asynchronously. Currently, my code looks something like this:

def myFunction(content):
   result = modify(content)
   send_mail('My Subject', result, 'me@example.com')
   return render(request, 'page.html', result)

Using Django-Mailer, I've figured out that I can cut loading time by writing the email to the database instead of sending it immediately, then having cron + Django mailer work through the emails in my database asynchronously.

However, I like to keep my database as free from potentially sensitive information as possible, and would like to avoid writing any of the emails sent through my app to my database. Even if the data is just being written for a short time, with automatic backups there's a possibility something might be saved.

I understand if there's no solution here, but is there a way to send emails asynchronously without every writing them to a database? I really don't think this is possible, but my ideal hope would be if there was a way to return the response, and then send the email.

def myFunction(content):
   result = modify(content)
   return render(request, 'page.html', result)
   send_mail('My Subject', result, 'me@example.com')

Django-After-Response seems to do this, but hasn't been updated since 2015.

This answer and this answer also provide potential solutions.

bones225
  • 1,488
  • 2
  • 13
  • 33
  • One thought I had could be skip sending the email, but after the result is returned, send another request to the server that emails it (that doesn't require a response) – bones225 Feb 06 '20 at 16:52
  • Well, I solved my problem, but I didn't answer the question. I switched from SMTP to API and it has decreased my mailing time by 90%. – bones225 Feb 06 '20 at 22:46

2 Answers2

1

You have a few options here. One way would be to have a task queue and a worker that executes those tasks.

I like using Django-RQ https://github.com/rq/django-rq , but Celery is another good option. Although with this you will need to have a worker instance running and also something to store the queue, like Redis.

For a simpler and quick solution I recommend trying django-background-tasks: https://django-background-tasks.readthedocs.io/en/latest/# This one stores the task queue in the database, but it takes care of it so you don't have to implement it yourself.

Dev Catalin
  • 1,265
  • 11
  • 25
  • Thanks for the answer. I am specifically looking to not write to the database. Otherwise, I would just use django-mailer. – bones225 Feb 06 '20 at 18:01
0

Use celery as a task queue and django-celery-email which is an Django e-mail backend that dispatches e-mail sending to a celery task.

Bilal Naqvi
  • 140
  • 1
  • 11