Writing Custom Management Commands in Djangoby Ather Rashid
Django is a free and open source python based web-framework that allows us to develop interactive web applications that too with easy to use syntax. Django is used by some of the leading websites in the world such as Pinterest, Instagram, Mozilla, The Washington Times, and Bitbucket. The main focus for django apps is reusability, apart from various other components that are present in the core package such as caching, internationalization, middleware, serialization to name a few.
While creating a new Django project django-admin and manage.py are automatically created. The difference between these two is that while django-admin is Django’s command-line utility for administrative tasks, manage.py takes extra care of a couple of things :
- It puts your project’s package on sys.path.
- It sets the DJANGO_SETTINGS_MODULE environment variable so that it points to your project’s settings.py file.
Now with manage.py in our project we can perform a number of tasks that come bundled with Django right out of the box. These tasks range from creating new apps to synching the database or loading data from provided fixtures to name from a few. Now this works fine when we use these commands but in order to perform some custom tasks we cannot be dependent on these commands. As such our custom tasks need custom commands. Django provides us much flexibility to create our custom commands. Now in order to create our custom management command there is a particular syntax which we need to follow.
Lets say we have our Django project named test_project in which we have one app installed for example account. So with this scenario our project structure would look a bit a like this:
Now in order to create our custom management command we need to create two python package management and commands inside our respective app folder with commands residing in management directory. In our commands python package we would be creating our custom command and let’s name it account_command.py. So after this change our project structure would be changed a little bit like this.
The custom management commands that we create are simply classes in Django inherited from django.core.management.base.BaseCommand. Now once we have setup our environment for creating commands let us see the syntax for writing custom management command. For example we will consider a management command that will create a sftp connection with a remote server and put files on a particular location.
Each file which contains a command must define a class called Command which derives from django.core.management.base.BaseCommand. So in our account_command.py use the following code,
from django.core.management.base import BaseCommand import pysftp from django.conf import settings class Command(BaseCommand): args = 'TAKES NO ARGUMENT' def handle(self, *args, **options): file = 'test.json' file_folder = settings.PROJECT_BASE_PATH + 'account' srv = pysftp.Connection(host='SFTP HOST', username='HOST_USERNAME', password='HOST_PASSWORD') srv.chdir('/srv/www/') filename = file_folder + '/' + file srv.put(filename)
In the above command the class command provides information of command regarding the command arguments whereas the handle method performs all tasks regarding required scenario of the project. In this way we can create a custom command depending upon the requirements of the project.