Guide to Sending Scheduled Reports Via Email Using Django & Celery

A Guide to Sending Scheduled Reports Via Email Using Django And Celery

Technology - 30 May 2017
Vaibhav Singh

In this blog post, we will implement sending out scheduled reports via email to our customers in a Django application using django-celery.

What is Celery?

We will be using Celery to schedule our reports. Celery is an asynchronous task queue based on distributed message passing. It also supports scheduling of tasks. There are two parts in Celery:

  1. Worker – Entity which manages the running of tasks in Celery.
  2. Broker – Celery communicates through messages, it is the job if the broker to mediate messages between client and worker. Some of the brokers are RabbitMQ and Redis.

Installing Celery

For Django projects, we will install django-celery which in turn installs celery as a dependency. Run this command to install django-celery:

pip install django-celery

Configuring Celery

Adding django celery configuration in

Assuming this is your project structure, we will create a Celery instance in the project folder called

Define your celery instance in project/project/

Now we need to make sure that celery is loaded when your django application starts. To ensure this import your celery instance in project/project/

Creating your reports modules

We will be creating a reporting module which will be customisable by the customer through the django admin interface.

Defining the models for the scheduled reports

We need the administrator of the app to customise the reports scheduling using cron expressions, to evaluate the cron expressions we are using croniter.

The administrator can schedule the reports from the admin interface by entering a cron expression, based on which the reports will be sent out.

Overriding Django form for validation

We will be creating a custom form so that we can validate that the cron expression entered by the user is valid. We are going to hide the last_run_at and next_run_at from the user as it would be irrelevant to them.

Creating an admin interface for the Scheduled Reports

Creating your reports email service

Create a file project/project/ This module consists of the scheduled reports’ emailing service.

Scheduling your email service

Once our email service is ready, we need to schedule the email service in celery. Create a file in project/project. We are using celery’s cron based periodic tasks for scheduling our reports.

We have scheduled to run the email service every minute, you can change it based on your requirements. The celery worker will call the email service every minute and which ever reports are due, will be sent out and, their next_run_at and last_run_at attribute will be updated based on the cron expression.

Getting your service worker up and running

Running your celery worker is as simple as running a django server, just run the command:

python celery worker --beat --loglevel=info --without-gossip --without-mingle --without-heartbeat

Your worker is up and running in the background.


We are using Django’s broker only for development for production, we would need Redis, RabbitMQ or some other broker service which is robust and scalable. Also in production you would need to run celery as a daemon. Here is the link to the documentation for Daemonization.


We now have a scheduled reporting module which provides the application’s administrator enough flexibility to schedule reports through Django’s admin interface, by simply specifying the cron expression as to when the report needs to be sent out.

Free tag for commerce

E-book on Digital Business Transformation