This Django website has a module that allows tasks to be scheduled and automatically executed at specific times in the background. The website saves the details of each job and its execution on its database. This means that the website module can perform tasks automatically without human intervention, making it more efficient.
Install python modules
pip install django
pip install APScheduler
- Start a Django project
django-admin startproject scheduler
- Change the current working directory to the "scheduler" directory
cd scheduler
- Start a Django app
django-admin startapp home
The settings.py file is a module that contains the configuration settings for a Django project. It includes various settings such as database configuration, installed apps, middleware, static file paths, and many more.
Add home to the INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'home',
]
Add SCHEDULER_DEFAULT to the settings.py
SCHEDULER_DEFAULT = True
The models.py file is a module that defines the data models for a Django app. A data model represents the structure of a database table and the relationships between different tables.
class Job(models.Model):
job_name = models.CharField(max_length=100)
next_run_time = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.job_name
- job_name : This field represents the name of the job.
- next_run_time : This field represents the date and time of the next execution of the job
class JobExecution(models.Model):
job = models.ForeignKey(Job, on_delete=models.CASCADE)
runtime = models.DateTimeField(auto_now_add=True)
error = models.TextField(null=True, blank=True)
status = models.CharField(max_length=100)
def __str__(self):
return f"{self.job} - {self.runtime}"
- job : Map the job execution with job.
- runtime : This field Contains time of execution of the job.
- error : This field contains any error message that may have occurred during the execution of the job.
- status : This field represents the status of the job execution like Running,Success,Failed.
The admin.py is a module that allows you to define the configuration of the Django admin interface for your models. This module defines the appearance and functionality of the admin interface, including which fields are displayed and how they are displayed, what filters are available, and what actions can be taken on individual objects or groups of objects.
from .models import Job,JobExecution
admin.site.register(Job)
admin.site.register(JobExecution)
python manage.py makemigrations
This command is used to create new database migrations based on the changes you have made to your Django models. A database migration is a file that contains instructions for how to modify the database schema to match your model changes. Running this command generates the migration files, which you can review and then apply to the database using the migrate command.
python manage.py migrate
This command is used to apply database migrations to the database. It reads the migration files that were generated by the makemigrations command, and applies them to the database to create or modify tables, columns, and other database objects. Running this command ensures that your database schema is up-to-date with your Django models.
python manage.py createsuperuser
Username: scheduler
Email address: scheduler@gmail.com
Password:
Password (again):
This command is used to create a new superuser account in your Django project. A superuser is a user with all permissions and can access the Django admin interface. Running this command prompts you to enter a username, email, and password for the new superuser account. Once created, you can use the superuser account to log in to the Django admin interface and manage your project's data.
The jobs.py module includes the function that needs to be executed by the scheduled job in the background. This function can be defined based on the specific requirements of the job that needs to be executed. The function can perform any task that needs to be executed at a specific interval, such as sending emails, updating the database, performing calculations, or fetching data from an external API. The function can be created with the necessary arguments and logic to perform the task, and it can be scheduled to run at specific time using the APScheduler library.
import datetime
#job1
def print_hello():
print("Helo world !")
#job2
def print_time():
print(datetime.datetime.now())
I am creating a simple function to print helo world! and current date and time in console.
The Scheduler.py is a module that provides the main scheduling functionality. It allows you to define, schedule, and run jobs at specific times. The scheduler.py module works in conjunction with the jobs.py module, which defines the specific functions or tasks that need to be executed by the scheduler. The scheduler.py module typically includes the creation of a scheduler object, which is used to schedule and manage the execution of jobs.
- import the necessary libraries
from apscheduler.schedulers.background import BackgroundScheduler
from dateutil.relativedelta import relativedelta
from django.utils import timezone
from .models import Job, JobExecution
from .jobs import *
- Define the function to run the job
def run_job(job, function, year, month, day, hour, minute, second):
# Create a job execution instance with status 'running'
job_execution = JobExecution.objects.create(job=job, status='running')
try:
# Execute the specified function
function()
# If successful, update the job execution instance with 'success' status and 'No Error' message
job_execution.status = 'success'
job_execution.error = 'No Error'
# Update the next run time of the job
job = Job.objects.get(pk=job.pk)
time_interval = relativedelta(years=year,months=month,days=day,hours=hour,
minutes=minute,seconds=second)
job.next_run_time = timezone.now() + time_interval
job.save()
except Exception as e:
# If there's an error, update the job execution instance with 'failed' status and the error message
job_execution.error = str(e)
job_execution.status = 'failed'
finally:
# Save the job execution instance
job_execution.save()
- Create the Scheduler Instance
# Create a background scheduler instance with the current timezone
scheduler = BackgroundScheduler(timezone=timezone.get_current_timezone())
- Define and Create Jobs
# Define job 1 with a unique name
job1, created = Job.objects.get_or_create(job_name='print Hello')
# Define job 2 with a unique name
job2, created = Job.objects.get_or_create(job_name='print Hi')
- Schedule Jobs
# Schedule job 1 to run every minute with an initial delay of 30 seconds
if created or Job.objects.filter(job_name=job1).exists():
scheduler.add_job(run_job, 'cron', args=[job1, print_hello, 0, 0, 0, 0, 1, 0], minute="*", second=30)
since minute="*" so 1 should be put in minute index
# Schedule job 2 to run every 5th minute of every hour with an initial delay of 39 seconds
if created or Job.objects.filter(job_name=job2).exists():
scheduler.add_job(run_job,'cron',args=[job2,print_time,0,0,0,1,0,0],hour="*",minute=5,second=39)
since hour="*" so 1 should be put in hour index
- Start the Scheduler
scheduler.start()
The apps.py file is used to define the configuration of a Django application.Apps.py file contains a class called AppConfig which defines various attributes and methods for the application. These attributes and methods.
from django.apps import AppConfig
from django.conf import settings
class HomeConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'home'
def ready(self):
if settings.SCHEDULER_DEFAULT:
from . import scheduler
The ready() function is called when the application is loaded. This method can be used to perform any necessary initialization or setup tasks for the application.
To prevent the runserver command from being executed twice in Django's manage.py file, the following code can be added
if "runserver" in sys.argv:
sys.argv.append("--noreload")
This code checks if the runserver command is in the list of command-line arguments (sys.argv) and if the --noreload option has not already been added to the arguments. If both conditions are true, it appends the --noreload option to the list of arguments.The --noreload option disables Django's auto-reloading feature, which can cause issues if the runserver command is executed multiple times. By preventing the command from being executed twice and disabling auto-reloading, this code helps to ensure a more stable and reliable development environment.
If you have any feedback, please reach out to us at santhoshparthiban2002@gmail.com