Often times during Django project development, there is a need to write one-off scripts that do something. As a self-taught developer, there are many ways to accomplish this, and I for one, did this completely wrong for years. My original strategy as a beginner-interediate level developer was to create view functions that contained my logic alongside URLs that ran those functions. These URLs would simply run my logic, then return a basic HTTP response of “success”. While this may be practical for beginners, it is not convenient, will clutter the views.py module, and is definitely not secure.
Enter custom django-admin commands.
Django-admin commands are commands that can be accessed the same way as “python manage.py runserver”. They can exist within any installed app within your project, and they have easy access to all data models you may need to manipulate or manage. Before we get into how to create them, here are some use cases that may get your mind rolling:
- Clean-up inactive or expired user accounts
- Send a summary email report to site administrators
- Send notifications to users based on custom business logic
Let’s get into how this is done.
Create a directory within your desired app named “management”
The file structure should mirror [project directory]/[app directory]/[management directory].
Create a child directory within “management” named “commands”
The file structure should now mirror [project directory]/[app directory]/[management directory]/[commands directory]
Create a python file (.py) with the name of your command
The name of this file will be how you will access it through the command prompt. For the sake of the tutorial, I have called mine “my_command.py”. Give your script a valuable and simple name for ease of use.
Confirm that your file structure looks like the following:
Now that we have the proper file structure for Django to recognize this as an admin command, lets take a look at how Django enforces we write them.
We must now create a class called Command that extends Django’s BaseCommand class. Within this class, we can set a help string to define the purpose of our command. Create a function called handle that takes the listed arguments: self, *args, and **options. It is within handle that we can carryout whatever logic is needed.
Try writing some simple logic in your handle function. For testing purposes, a simple print statement will suffice, but if you are working in an exisiting project, try importing some models and modifying your database. Once you have your desired logic, run “python manage.py [my_command]” from the command prompt and within your project directory.
If Django does not recognize your command, double check your file structure and code; make sure your app is installed in your project settings.py.
You have now written what is most likely your first Django-admin command function. These are especially useful for automating database maintenance, admin reporting, and periodic app-specific tasks.
As a bonus, try setting up a scheduled task that runs your command. This can be done locally through Windows Task Scheduler, in production in a PythonAnywhere Scheduled Task or through many other platforms.
Please comment your thoughts or any tips and tricks you learn as you begin leveraging this new skill.