Prerequisites: Django Introduction and Installation
Manage.py in Django is a command-line utility that works similar to the django-admin command. The difference is that it points towards the project’s settings.py file. This manage.py utility provides various commands that you must have while working with Django. Some of the most commonly used commands are –
- python manage.py startapp
- python manage.py makemigrations
- python manage.py migrate
- python manage.py runserver
Interestingly we can create our own Custom Management Commands to fulfill a wide variety of requirements ranging from interacting with our application using the command line to serve as an interface to execute Cron Jobs. We are going to create a custom Management Command which gives us the stats or metrics of new articles published, comments on those articles on a particular day.
Getting Started
Follow Django Introduction and Installation to setup a virtual environment and install Django
Step 1: Initialize a project by following command
django-admin startproject geeks_site
Step 2: Create an app named blog
python manage.py startapp blog
Step 3: Add your app to the settings.py
In geeks_site/settings.py
Python3
INSTALLED_APPS = [
'django.contrib.admin' ,
'django.contrib.auth' ,
'django.contrib.contenttypes' ,
'django.contrib.sessions' ,
'django.contrib.messages' ,
'django.contrib.staticfiles' ,
'blog' ,
]
|
Step 4: Create Models named Article and Comment in the blog app
Model Article :
- Fields :
- title: Stores the title of an article
- body: Content of that article
- created_on: Date and Time on which that article was created
Model Comment :
- Fields :
- article: Article on which comment is created
- text: Actual comment
- created_on: Date and Time on which that article was created
In blog/models.py
Python3
from django.db import models
class Article(models.Model):
title = models.CharField(max_length = 200 )
body = models.TextField()
created_on = models.DateTimeField(auto_now_add = True )
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete = models.CASCADE)
text = models.CharField(max_length = 200 )
created_on = models.DateTimeField(auto_now_add = True )
|
Step 5: Register your model in blog/admin.py so that it shows up in the admin panel.
In blog/admin.py
Python3
from django.contrib import admin
from .models import Article, Comment
admin.site.register(Article)
admin.site.register(Comment)
|
Step 6: Now, To migrate all your changes and start the server, run the following commands in your terminal
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Create a superuser account to log in to the admin panel
python manage.py createsuperuser
Now, Visit the admin panel at http://127.0.0.1:8000/admin/

Create some articles and then some comments :


Now, Let’s start working on the creation of Custom Django Management Commands
- Add a management/commands directory to the blog app
- Add __init__.py to blog/management and __init__.py + stats.py files to blog/management/commands directory
Note: Django will register a manage.py command for each Python module in that directory whose name doesn’t begin with an underscore
The folder structure of the blog app looks like this :

We will use python manage.py stats to run our custom management command. Now we will configure what actually this command will do.
In stats.py
Python3
from django.core.management.base import BaseCommand
from django.db.models import Count
from blog.models import Article, Comment
from datetime import timedelta, datetime
from django.utils.timezone import utc
def now():
return datetime.utcnow().replace(tzinfo = utc)
class Command(BaseCommand):
help = 'Displays stats related to Article and Comment models'
def handle( self , * args, * * kwargs):
From = now() - timedelta(hours = 5 )
To = now()
articles_published_in_last_5_hour = Article.objects. filter (
created_on__gt = From, created_on__lte = To).count()
comments_published_per_article = Comment.objects. filter (
created_on__gt = From, created_on__lte = To).values(
'article' ).annotate(count = Count( 'article' )).order_by()
print ( "Articles Published in last 5 hours = " ,
articles_published_in_last_5_hour)
print ( "Comments per Article in last 5 hours" )
for data in comments_published_per_article:
print (data)
|
Understanding the stats.py file
Basically, a Django management command is built from a class named Command which inherits from BaseCommand.
1) help: It tells what actually the command does. Run the following command and see the help
python manage.py stats --help
2) handle(): It handles all the logic which needs to be executed when the command is executed. Let’s understand of code inside handle() method
- Here we are concerned about the following two stats
- Number of articles which were published in last 5 hours
- Number of comments created in last 5 hours per article
- From: Current time – 5 hours
- To: Current Time
- articles_published_in_last_5_hour : an integer value
- comments_published_per_article : queryset object or a list of dictionaries
- print statements to output data on terminal
Now, Run the following command in your terminal :
python manage.py stats
Output :

Adding Arguments
Django uses the argparse module to handle the custom arguments. We need to define a function add_arguments under the command class to handle arguments.
Python3
from django.core.management.base import BaseCommand
from django.db.models import Count
from app.models import Article, Comment
from datetime import timedelta, datetime
from django.utils.timezone import utc
def now():
return datetime.utcnow().replace(tzinfo = utc)
class Command(BaseCommand):
help = 'Displays stats related to Article and Comment models'
def add_arguments( self , parser):
parser.add_argument( '-t' , '--time' , type = int , help = 'Articles published in last t hours' )
def handle( self , * args, * * kwargs):
t = kwargs[ 'time' ]
if not t:
t = 5
From = now() - timedelta(hours = t)
To = now()
articles_published_in_last_t_hour = Article.objects. filter (
created_on__gt = From, created_on__lte = To).count()
comments_published_per_article = Comment.objects. filter (
created_on__gt = From, created_on__lte = To).values(
'article' ).annotate(count = Count( 'article' )).order_by()
print (f "Articles Published in last {t} hours = " ,
articles_published_in_last_t_hour)
print (f "Comments per Article in last {t} hours" )
for data in comments_published_per_article:
print (data)
|
Output:

Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
06 Aug, 2021
Like Article
Save Article