In this article, I'll discuss the Django management commands you should know as a beginner or advanced developer. So, without further ado, let's get started to explore the core commands available in Django and other libraries and how to write your custom management commands.
Before going further, let us understand the importance of the management command. A command is a simple Python module extended by a Django base command, and this module is mainly used as Django's command-line utility for administrative tasks. To run any Django management commands, we use the manage.py module; this module is auto-generated at the root folder level when we install the Django project.
As an alternative to manage.py, we can use django-admin to execute the management commons. So in our below discussions, we will prefer the manage.py command-line utility.
Table of contents 📝
- Explanation of the Django core commands.
- Other library extension Django commands.
- Custom Django commands.
1. Explanation of the Django core commands.
When we are working on any projects, we list all the available management commands using python manage.py, so I created simple Django project in which I can see most of the Django core management commands.
python manage.py
Type'manage.py help <subcommand>' for help on a specific subcommand.
Available subcommands:
[auth]
changepassword
createsuperuser
[contenttypes]
remove_stale_contenttypes
[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
optimizemigration
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver
[sessions]
clearsessions
[staticfiles]
collectstatic
findstatic
runserver
these core commands are available in
my_virtual/lib/{your python version}/site-packages/django/core/management/commands
location
➡️ runserver
python manage.py runserver
The runserver command is used to run the Django server, but by default, when we run this command, Django will run at port 8000.
Watching for file changes with StatReloader
Performing system checks…
System check identified no issues (0 silenced).
September 04, 2024–01:40:06
Django version 4.2.16, using settings 'hemanth.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
we can also change the port to any port number, here I changed it to 3000
python manage.py runserver 3000
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
September 04, 2024 - 01:41:33
Django version 4.2.16, using settings 'hemanth.settings'
Starting development server at http://127.0.0.1:3000/
Quit the server with CONTROL-C.
for runserver, you can pass some extra options like
[--nothreading] [ --noreload] [--nostatic] [ --insecure] [--version] [--settings SETTINGS]
[ — pythonpath PYTHONPATH] [ — no-color] [ — force-color] [ — skip-checks]
[addrport]
For example, when we make any code changes, the Django server does an auto-reload using the runserver command, but we can disable this auto-reload using the no-auto-reload option with the runserver
$ python manage.py runserver --noreload
➡️ collectstatic
To use this command, make sure you have the django.contrib.staticfiles app inside the application definition that is INSTALLED_APPS.
python manage.py collectstatic
When we run this command, Django will collect all the static files in our project and put them in the destination folder. That destination folder we need to define in the settings.py file using STATIC_ROOT.
for example
STATIC_ROOT = os.path.join(BASE_DIR, 'whole-static')
python manage.py collectstatic
125 static files copied to '/home/{my laptop folders}/hemanth/whole-static'.
➡️ createsuperuser
used to create a Django superuser so that this user can log in to http://127.0.0.1:8000/admin.
$ python manage.py createsuperuser
Username (leave blank to use 'hemanth'): hemanth
Email address: [email protected]
Password:
Password (again):
Superuser created successfully.
➡️ changepassword
used to change the given username and password
$ python manage.py changepassword hemanth
Changing password for user 'hemanth'
Password:
Password (again):
Password changed successfully for user 'hemanth'
inside the changepassword module, this was the code
u = User.objects.get(username="hemanth")
u.set_password("enterd_password")
u.save()
➡️ check
used to check the entire Django project for potential problems. For example, when we define the wrong field option in the model's field like (fields.W340) null does not affect ManyToManyField.
python manage.py check
or when we want to deploy our project at that time, we can use this
python manage.py check --deploy
➡️ dbshell
This will activate the PSQL command line for the given database. in this example, I am using PostgreSQL DB
$ python manage.py dbshell
Signals Started
psql (14.13 (Ubuntu 14.13–0ubuntu0.22.04.1), server 12.18 (Ubuntu 12.18–0ubuntu0.20.04.1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
vip=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------------+----------+----------+---------+-------+-----------------------
asd | postgres | UTF8 | en_IN | en_IN |
car | postgres | UTF8 | en_IN | en_IN |
➡️ diffsettings
Displays differences between the current settings.py and Django's default settings. However, we never used this.
$ python manage.py diffsettings
➡️ Flush
This will remove all the data from the database except migrations; however, never use this production
$ python manage.py flush
You have requested a flush of the database.
This will IRREVERSIBLY DESTROY all data currently in the "/home/project/hemanth/db.sqlite3" database,
and return each table to an empty state.
Are you sure you want to do this?
yes
Type 'yes' to continue, or 'no' to cancel: yes
➡️ inspectdb
This will display all the database tables from your default database to the Django model format, and this will help write the Django model from the existing database table.
$ python manage.py inspectdb
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models
class AuthGroup(models.Model):
name = models.CharField(unique=True, max_length=150)
class Meta:
managed = False
db_table = 'auth_group'
➡️makemigrations
This is one of the main utility commands after runserver; this one is used to generate migration files for your modified Django models, or if you installed any third-party libraries, so we also need to generate migration files. This migration file contains SQL commands and queries.
python manage.py makemigrations
# No changes detected
or
files will be generated.
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Student
➡️ migrate
After the migration files are generated, we need to apply those (our model changes) to the physical database, so at that time we need to use this command.
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
➡️ shell
shell is the interactive console where we can execute Django (only installed project packages and modules) or Python code for debugging purposes.
$ python manage.py shell
Python 3.9.19 (main, Apr 6 2024, 17:57:55)
[GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>> from django.contrib.auth.models import *
>>> User.objects.count()
0
➡️ showmigrations
This will display all the executed and not executed migration files (0002_student_age).
$ python manage.py showmigrations
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
[X] 0012_alter_user_first_name_max_length
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
polls
[X] 0001_initial
[ ] 0002_student_age
sessions
[X] 0001_initial
➡️ startapp
This command will be used to create the Django apps, and after creating the app, make sure to include the installed app. For example, I created polls apps and included them in the installed app section.
python manage.py startapp polls
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls'
]
➡️ startproject
This is the first command used to create the Django project.
python manage.py startproject my_project_name
➡️ test
This command will be used to run all the Django test cases that we usually write inside all the apps.
python manage.py test
Found 0 test(s).
System check identified no issues (0 silenced).
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Ran 0 tests in 0.000s
OK
➡️ testserver
This command is a combination of loaddata and runserver commands. We can use this to run a server with some initial data, and this data will be loaded into a new test db.
$ python manage.py testserver
Creating test database for alias 'default'…
CommandError: Error: No database fixture specified. Please provide the path of at least one fixture in the command line.
➡️ clearsessions
This will clear all the session data stored in the defined module; this is the default module to store the session data.
$ python manage.py clearsessions
# The module to store session data
SESSION_ENGINE = "django.contrib.sessions.backends.db"
➡️dumpdata
If we need a dump of data either from a database or a particular table or model in JSON format, then we can use the command; this will display the model's data in the given format by default as JSON.
For example, I need only a dump of all models inside the Polls app; in that case, I use this command in this format by passing the Polls app.
python manage.py dumpdata polls
[
{
"model": "polls.student",
"pk": 1,
"fields": {
"name": "hemanth",
"age": "90"
}
},
{
"model": "polls.student",
"pk": 2,
"fields": {
"name": "joy",
"age": "89"
}
}
]
If we need a JSON file instead of displaying the dump, then
$ python manage.py dumpdata polls > polls_dump.json
this command will create the dump file in the root folder.
➡️ loaddata
to load the dumped data into our models, then we can use this command
$ python manage.py loaddata polls_dump.json
Installed 2 object(s) from 1 fixture(s)
Note: While using load data, keep an eye on the primary key because if the same objects are already there in the database, those from the fixture with the same primary key will be updated, or else an object will be created.
2. Other library extension Django commands.
There are many third-party packages; however, Django extensions are the most important and most used ones.
Before displaying what are all the management commands in this package, let us install the package first.
install the package.
$ pip install django-extensions
Add this app to the installed apps section.
INSTALLED_APPS = [
...
'django_extensions',
...
]
now display all the commands
$ python manage.py
[django_extensions]
admin_generator
clean_pyc
clear_cache
compile_pyc
create_command
create_jobs
create_template_tags
delete_squashed_migrations
describe_form
drop_test_database
dumpscript
export_emails
find_template
generate_password
generate_secret_key
graph_models
list_model_info
list_signals
mail_debug
managestate
merge_model_instances
notes
pipchecker
print_settings
print_user_for_session
raise_test_exception
reset_db
reset_schema
runjob
runjobs
runprofileserver
runscript
runserver_plus
set_default_site
set_fake_emails
set_fake_passwords
shell_plus
show_template_tags
show_urls
sqlcreate
sqldiff
sqldsn
sync_s3
syncdata
unreferenced_files
update_permissions
validate_templates
So in total, this Django extension package gives 47 utility commands. we will explore only what we use every day
➡️ clean_pyc
This will delete all the.pyc (python bytecode compiled files from the project.") from the projects that were by default created by Python and available inside this __pycache__ folder.
$ python manage.py clean_pyc
➡️ create_command
This will be used to create a scaffold to create custom management commands, and I will explain how to write custom management commands in a later section of the article.
So, for example, I want to create a Django management command directory structure in the polls app. The create_command will create a folder structure in the Polls app with the sample.py module as an example.
$ python manage.py create_command polls
➡️describe_form
the command used to auto-generate and display the Django form format of the given model
$ python manage.py describe_form polls.student
from django import forms
from polls.models import Studentclass StudentForm(forms.Form):
name = forms.CharField(label='Name', max_length=100)
age = forms.CharField(initial=1, label='Age', max_length=100)
➡️ generate_password
This will be used to generate the random password based on the Django core's default password generator, BaseUserManager.make_random_password() method.
$ python manage.py generate_password --length=100
The output will be like this; the length parameter is a must.
3T35szkZ6xc79Gg8Q3AuqJz6VRwCptsmkePss7rcxR7V4KGdFAZNtFXerg88RQ4tbDNPqqsM5VtH5A4HwZXsNfVMYgzwS5ERRHrQ
➡️ graph_models
used to generate the graph relation of models in different output formats; for example, let me create a graph model for the entire project.
$ python manage.py graph_models polls -a -o myapp_models.png
CommandError: Neither pygraphviz nor pydotplus could be found to generate the image. To generate text output, use the — json or — dot options.
so I installed pydotplus
$ pip install pydotplus
in the root folder, the image was created
or we can generate for one app, like this
$ python manage.py graph_models polls -o myapp_models.png
➡️ list_model_info
command, which lists given model fields and methods.
$ python manage.py list_model_info --model=polls.student
polls.Student
Fields:
id -
name -
age -
Methods (non-private/internal):
adelete()
arefresh_from_db()
asave()
get_constraints()
validate_constraints()
Total Models Listed: 1
➡️ notes
will print all annotations like TODO, FIXME, BUG, HACK, WARNING, NOTE, or XXX in your py and HTML files
for example
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
# TODO make
age = models.CharField(max_length=100, default=1)
$ python manage.py notes
/home/hemanth/polls/models.py:
* [ 7] TODO make
➡️ pipchecker
will display all the outdated pip packages by scanning our requirements.txt file.
$ python manage.py pipchecker
for example
amqp 5.1.1 5.2.0 available
annotated-types 0.6.0 0.7.0 available
anyio 4.3.0 4.4.0 available
.....................
.....................
➡️ raise_test_exception
If you want to raise an exception instead of manually raising it while installing a third-party library like Sentry, for example, after integrating Sentry, we need to test Sentry to see if it is catching our exception or not to do data. The documentation mentioned creating an API with logic 1/0 so that an error will occur, but instead of doing all this, we can simply run these commands.
$ python manage.py raise_test_exception
django_extensions.management.commands.raise_test_exception.DjangoExtensionsTestException: This is a test exception via the
django-extensions raise_test_exception management command.
➡️ reset_db
this deletes all the data from your database, so keep an eye on the production
$ python manage.py reset_db
You have requested a database reset.
This will IRREVERSIBLY DESTROY
ALL data in the database "/home/hemanth/Downloads/hemanth/db.sqlite3".
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: yes
Reset successful.
➡️ shell_plus
This is exactly like Django Shell, but it has a lot of features, like autoloading all models, and we can pass some extra parameters that will be helpful to debug SQL queries.
for example, here our student model is also pre-loaded
$ python manage.py shell_plus
# Shell Plus Model Imports
from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.models import Session
from polls.models import Student
# Shell Plus Django Imports
from django.core.cache import cache
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import transaction
from django.db.models import Avg, Case, Count, F, Max, Min, Prefetch, Q, Sum, When
from django.utils import timezone
from django.urls import reverse
from django.db.models import Exists, OuterRef, Subquery
use this parameter to print SQL
$ python manage.py shell_plus --print-sql
>>> Student.objects.all()
SELECT "polls_student"."id",
"polls_student"."name",
"polls_student"."age"
FROM "polls_student"
LIMIT 21
Execution time: 0.000413s [Database: default]
<QuerySet []>
There are so many other parameters available with this command; please check it out; it will be helpful to understand the query performance.
➡️ show_urls
This will display all the URLs in our project
$ python manage.py show_urls
/admin/ django.contrib.admin.sites.index admin:index
/admin/<app_label>/ django.contrib.admin.sites.app_index admin:app_list
/admin/<url> django.contrib.admin.sites.catch_all_view
............
............
3. Custom Django management commands.
We can create custom Django management commands; the folder structure needs to be exactly like this: app → management →commands → file. sample.py is my new management command.
Here sample.py is our command; however, if we add an underscore before the file name, like _example.py, then this example command will not be available as a management command.
To consider the smaple.py module as the management command, the only requirement is that it must define a class
Command
that extendsBaseCommand
or one of its
sample.py module
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "My shiny new management command."
def handle(self, *args, **options):
print("my new command")
The handle method is the entry point to execute the script and our sample command is ready, Let me execute this command
$ python manage.py sample
my new command
When we executed the sample command, our print statement was executed from the handle method. this means our custom management command is working fine,
Now let me pass named arguments to the handle method using the add_arguments(self, parser) method, and this argument we usually pass when we execute the command.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "My shiny new management command."
def add_arguments(self, parser):
parser.add_argument(
"--name", help="any string", default="boss"
)
def handle(self, *args, **options):
print(f"hi {options['name']}")
I overrided the add_arguments
to pass dynamic values to my script with a key name. Let me execute the modified module.
$ python manage.py sample
hi boss
it prints "hi boss", The boss value is coming from the default value from the add_argument method.
$ python manage.py sample --name=hemanth
hi hemanth
Now it printed "hi hemanth" because I passed hemanth as value.
Note: parser.add_arguments supports many useful arguments like action, dest, help, default, etc.
- for example, let me make use of the dest parameter.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "My shiny new management command."
def add_arguments(self, parser):
parser.add_argument(
"--name", help="any string", default="boss", dest="my_name"
)
def handle(self, my_name, *args, **options):
print(f"hi {my_name}")
In the above code, I added the dest keyword argument to the add_argument method, which means we can use the dest value as one of the first parameters in the handle method.
Instead of print statements, we can use something like this for better readability
def handle(self, my_name, *args, **options):
self.stderr.write(f"hi {my_name}")
self.stdout.write(self.style.MIGRATE_HEADING(f"hi {my_name}"))
$ python manage.py sample
Final thoughts ☑️
The Django management command is such a powerful utility tool. We can use this as a simple Django script for more advanced scripts, and we explored different ways of integrating and writing custom commands. I hope this article gives some ideas to explore the management commands, and if you have any further questions, please add them in the space provided below.
Let's clap.
Still, most commands that we did not discuss here are briefly explained in Django documents; please have a look.
In Plain English 🚀
Thank you for being a part of the In Plain English community! Before you go:
- Be sure to clap and follow the writer ️👏️️
- Follow us: X | LinkedIn | YouTube | Discord | Newsletter
- Visit our other platforms: CoFeed | Differ
- More content at PlainEnglish.io