post-thumb

Introduction to management command in django

In this tutorial we will learn about the management command in django ad make some custom management command as well.

Django management command can be invoke with manage.py script.

simple example of managemet command  like while running development server, create new app are as follow:

1. python manage.py runserver

2.python manage.py startapp app_name

you can get more django default management command by running script python manage.py help 

python manage.py help
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

Note: you can run manage.py help <subcommand> to get more info about particular command as well.

manage.py help runserver
managee.py help collectstatic

 

 

Now time to learn about how to create custom management command. lets start it 🐱‍🏍🐱‍🏍

For that you need to create management directory inside your app and inside it make commands directory as shown below.

my_site/
    my_app/
        models.py
        views.py
        management/
            __init__.py
            commands/
                __init__.py
                my_command.py

File name mention inside commands directory is used to run the aprticular custom command .

python manage.py my_command

 

Example 1 :

Lets create custom management command to display current datetime for the create a python file as current_datetime inside commands directory in your app

from django.core.management.base import BaseCommand
from django.utils import timezone

class Command(BaseCommand):

    def handle(self, *args, **kwargs):
        current_time = timezone.now()
        self.stdout.write("current time is %s" % current_time)

run command to show output.

python manage.py current_datetime

output:

current time is 2023-08-05 03:29:36.958432+00:00

 Example-2:

management command to delete all the post 

management/commands/delete_post

from django.core.management.base import BaseCommand
from post.models import Post

class Command(BaseCommand):
    help = 'Custom Management commad example'

    def handle(self, *args, **kwargs):
        try:
            Post.objects.all().delete()
            self.stdout.write(self.style.SUCCESS('all the posts are deleted successfully'))
        except Exception as e:
            self.stdout.write(self.style.ERROR("error %s" % e))

 

Example-3:

You can also pass arguments to the custom management command for this we need to define a method named add_arguments.

from django.core.management.base import BaseCommand
from post.models import Post

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('post_id')

    def handle(self, *args, **kwargs):
        post_id = kwargs['post_id']
        try:
            post = Post.objects.get(id=post_id)
            post.delete()
            self.stdout.write(self.style.SUCCESS('post %s deleted successfully' % post_id))
        except Post.DoesNotExist:
            self.stdout.write(self.style.WARNING('post with id %s doesn\'t exist' % post_id))
        except Exception as e:
            self.stdout.write(self.style.ERROR('error %s' % e))

you can now provide argument with in command line to delete the particular post like

python manage.py delete_post 3

 

Example-4:   Custom management commad with optional arguments.

In order to declare an argument as an optional argument, you need to add hyphen - in front of that variable. And you can pass optional arguments in any order.

In Below example: if post id is sent then only that post will be deleted else if no post id is sent then all posts will be deleted.

from django.core.management.base import BaseCommand
from post.models import Post

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('-post_id')

    def handle(self, *args, **kwargs):
        post_id = kwargs.get(‘post_id’, None)
        try:
            if post_id:
                post = Post.objects.get(id=post_id)
                post.delete()
                self.stdout.write(self.style.SUCCESS('post %s deleted successfully' % post_id))
            else:
                Post.objects.all().delete()
                self.stdout.write(self.style.SUCCESS('all the posts are deleted'))
        except Exception as e:
            self.stdout.write(self.style.ERROR('error %s' % e))
python manage.py delete_post -post_id 3

https://docs.djangoproject.com/en/3.0/howto/custom-management-commands/

 

 

Dump and load data in django

data dump

datadump command is used to export data to a file (fixture)

./manage.py dumpdata > dump_`date +%d-%m-%Y`.json

data load

loaddata command is used to restore the fixture into the database

./manage.py loaddata dump.json

Export data of specific app

./manage.py dumpdata app_name > dump.json

Export data of specific app table

./manage.py dumpdata app_name.tabel_name > dump.json

Exclude specific app from dump data

./manage.py dumpdata —exclude app_name > dump.json

Exclude specific app table from dump data

./manage.py dumpdata --exclude app_name.table_name > dump.json

 

Formate in dump data

Django dumpdata allow you to dump data in JSON, XML, or YAML. By default, dumpdata will format its output in JSON

./manage.py dumpdata app_name —format yaml > dump.yaml

 

Indent in dump data

./manage.py dumpdata -indent 2 > dump.json

Output

[
{
  "model": "contenttypes.contenttype",
  "pk": 1,
  "fields": {
    "app_label": "admin",
    "model": "logentry"
  }
},
{
  "model": "contenttypes.contenttype",
  "pk": 4,
  "fields": {
    "app_label": "auth",
    "model": "user"
  }
},
]

Exporting data to be load in another database

Example #1

python manage.py dumpdata --exclude auth.permission --exclude contenttypes --indent 2 > dump_`date +%d-%m-%Y`.json

 Example #2

python manage.py dumpdata --natural-foreign --natural-primary --exclude auth.permission --exclude contenttypes --indent 2 > dump_`date +%d-%m-%Y`.json

 

Import data in databse

./manage.py loaddata dump.json

 

Error handling 

Error

django.core.serializers.base.DeserializationError: Problem installing fixture

Fix

Remove all the WARNINGS messages from the fixture

Not Good

System check identified some issues:

WARNINGS:
ESC[33;1milovedjago.FieldReport.photo: (fields.W340) null has no effect on ManyToManyField.ESC[0m
ESC[33;1milovedjago.LogTrack.user: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
        HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.ESC[0m
[
{
  "model": "auth.user",
  "pk": 1,
  "fields": {
      .....

Good

[
{
  "model": "auth.user",
  "pk": 1,
  "fields": {