Mike Slinn
Mike Slinn

Django-admin and manage.py

Published 2021-02-12. Last modified 2021-03-28.
Time to read: about 2 minutes.

This article is categorized under Django.

django-admin

django-admin can be run for a specific Django webapp as manage.py. To set this up, right after running django-admin startproject to create a new Django webapp, make manage.py in the new directory executable:

Shell
$ chmod a+x manage.py

Notes on selected django-admin / manage.py subcommands follow. I discuss the dumpdata and test subcommands in separate blog posts. Additional sections that rely on manage.py subcommands conclude this blog post.

dbshell Subcommand

The dbshell subcommand of the manage.py command picks up the database parameters from Django settings for the webapp and passes them to the PostgreSQL psql command. A psql subshell can be spawned:

Shell
(aw) $ ./manage.py dbshell
psql (12.5 (Ubuntu 12.5-0ubuntu0.20.10.1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

frobshop=# 

A single SQL statement can be executed:

Shell
(aw) $ ./manage.py dbshell -- -tc 'select current_user'
postgres 

diffsettings Subcommand

The diffsettings subcommand displays differences between the current settings file and Django’s default settings.

Shell
(aw) $ ./manage.py diffsettings | less

loaddata Subcommand

Round-tripping the data involves first dumping the data from the database using the dumpdata subcommand, and then loading it from the dump file using the loaddata subcommand, like this:

Shell
(aw) $ ./manage.py loaddata frobshop/fixtures/all.json
Installed 706 object(s) from 1 fixture(s) 

The Django docs suggest that loading data from a fixture deletes pre-existing data in the affected tables. I wonder what the corner cases for this look like, for example a fixture that affects just a property of an app?

Each time you run loaddata, the data will be read from the fixture and re-loaded into the database. Note this means that if you change one of the rows created by a fixture and then run loaddata again, you’ll wipe out any changes you’ve made.

To test my understanding of this, I created an empty fixture:

Shell
(aw) $ echo '{}' > frobshop/fixtures/empty.json

Now I loaded the empty fixture:

Shell
(aw) $ ./manage.py loaddata frobshop/fixtures/empty.json
/var/work/django/oscar/lib/python3.8/site-packages/django/core/management/commands/loaddata.py:211: RuntimeWarning: No fixture data found for 'empty'. (File format may be invalid.)
  warnings.warn(
Installed 0 object(s) from 1 fixture(s) 

(aw) $ ./manage.py dumpdata
Lots and lots of JSON is output 

That did not go as expected. The documentation should say that affected records in the database will be overwritten. That is different from my understanding of the current phrasing, which suggests to me that the entire contents of affected tables are replaced.

runserver Subcommand

Run Django for development purposes on all IP addresses and port 8001:

Shell
(aw) $ ./manage.py runserver 0.0.0.0 8001

By default, the development server doesn’t serve static files. To change this, read Managing static files.

shell Subcommand

Individual Python expressions or entire programs can be executed from the Django environment by using the shell subcommand.

Shell
(aw) $ ./manage.py shell -h
usage: manage.py shell [-h] [--no-startup] [-i {ipython,bpython,python}] [-c COMMAND] [--version] [-v {0,1,2,3}]
                       [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color]

Runs a Python interactive interpreter. Tries to use IPython or bpython, if one of them is available. Any standard
input is executed as code.

optional arguments:
  -h, --help            show this help message and exit
  --no-startup          When using plain Python, ignore the PYTHONSTARTUP environment variable and ~/.pythonrc.py
                        script.
  -i {ipython,bpython,python}, --interface {ipython,bpython,python}
                        Specify an interactive interpreter interface. Available options: "ipython", "bpython", and
                        "python"
  -c COMMAND, --command COMMAND
                        Instead of opening an interactive shell, run a command as Django and exit.
  --version             show program’s version number and exit
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn’t provided,
                        the DJANGO_SETTINGS_MODULE environment variable will be used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Raise on CommandError exceptions
  --no-color            Don’t colorize the command output.
  --force-color         Force colorization of the command output.

A program can be piped in via STDIN:

Shell
(aw) $ cat > myprog.py << EOF
import django
print(django.__version__)
EOF

(aw) $ cat myprog.py | ./manage.py shell
3.1.6