Useful Django Shell Commands — Part 1

Useful Django Shell Commands — Part 1

Django provides many useful shell commands which can increase development efficiency and can prove a lifesaver in debugging.

We will explore useful flags which can enhance popular commands like runserver and migrate, and some other lesser-known but useful shell commands.

1. verbosity

Verbosity flag defines the number of logs printed by the command it has flagged.

python manage.py runserver --verbosity 2

In the above example, the verbosity flag will govern the amount of logs printed by the runserver command. Verbosity has three levels, 0, 1, 2, 3

  • 0 means no output
  • 1 means normal output (default)
  • 2 means verbose output
  • 3 means very verbose output

Used judiciously, verbosity can help with both the problem of too little and too many logs!

This flag can be used with any of the Django shell commands. For .e.g. try:
python manage.py makemigrations --verbosity 3
python manage.py migrate --verbosity 1

2. showmigrations

We all have run into Django migrations issues where the b̶e̶s̶t easiest way forward is to delete the database and run migrations afresh. Though, if it is not a local environment, you have to get your hands dirty to debug, and showmigrations can prove a useful tool.

In a nutshell, showmigrations show the list of all migrations and identify which ones are applied and which aren’t.

python manage.py showmigrations

Output:

admin  
 [X] 0001_initial  
 [X] 0002_logentry_remove_auto_add  
 [X] 0003_logentry_add_action_flag_choices  
auth  
 [X] 0001_initial  
 [] 0002_alter_permission_name_max_length

The above output shows that all migrations of the admin app have been applied and one migration of auth app is still unapplied.

In detail, showmigrations identify migrations whose changes have been applied or incorporated in the database. It uses a cross [X] sign in front of such migrations. Whereas, an empty sign [] is used to identify unapplied migrations i.e. migrations whose changes have not been incorporated in the database.

A very neat trick is to use verbosity alongside showmigrations like follows:

python manage.py showmigrations — verbosity 3

Output:

admin  
 [X] 0001_initial (applied at 2021–08–19 12:40:09)  
 [X] 0002_logentry_remove_auto_add (applied at 2021–08–19 12:40:09)

This will print timestamps when these migrations are applied and can be very useful for debugging.

3. shell

We are familiar with Python’s powerful interactive shell, where one can test out syntaxes, types, and object details. Django extended it into its shell which has project settings and configurations imported by default.

python manage.py shell

The above command will launch a shell that is much more impressive than what humble Django documentation gives it credit for.

Django shell allows users to import models, create their objects, test out Django features, triggers, and a lot more. It allows you to test out logic flows that might require elaborate test cases(ideally that test case should have been there!).

Having a problem with Django settings or you wish to debug a model’s post_save(), Django shell is to the rescue.

4. traceback

traceback can be considered a specialized tool, required rarely, but is useful where no one else can help.

Django management commands like runserver raise and shows the whole stack when an exception is raised, except in the scenario when CommandError is raised. In that scenario, it generally prints a single statement. CommandError is raised when the Django management command itself face a problem while executing.

python manage.py runserver -- traceback

The above command will print the whole exception stack even in the case of CommandError.

The above mentioned flags and commands can be fully utilized only if they are incorporated in everyday development practice. It is like using debugger instead of print() command, needs a little initial effort, but repays exponentially if fully explored.

Comment your favorite Django commands and hack and what you feel about the above-mentioned commands.

That’s all for this blog, thank you!