How to Check the Running Django Command
It’s occasionally useful to be able to tell which Django
manage.py command is being run, in a code path that otherwise has no way of telling. For example, in Speed Up Your Django Tests, I describe how to modify
manage.py to default use a test settings file when the
test command is run.
The way to do this is to check the second element of
sys.argv, which is what Django’s
ManagementUtility.execute() does. You can do this succinctly like:
import sys if sys.argv[1:2] == ["test"]: # Something specific to running "test" ...
This code works even when
sys.argv has fewer than two elements, because slicing beyond the end of a list returns an empty list.
While sometimes useful to change a default or add some instrumentation, I’d use this pattern with caution. Such changes will be hard to debug since they’re “at a distance”.
It’s normally possible to instead override another part of the given command. In particular, you can write a custom management command that imports and wraps the built-in one, as I showed in Make Django Tests Always Rebuild the Database if It Exists.
I’ve seen several a few community resources suggesting a similar pattern. However, rather than checking exactly
sys.argv they check it with the
import sys if "test" in sys.argv: # WRONG! # Something specific to running "test" ...
This is imprecise. It will correctly set the default if you run
python manage.py test, because then
sys.argv will be
["manage.py", "test"]. But perhaps weeks, months, or years after you added this pattern and forgot about it, you might run a command like
python manage.py delete-books --names test. Then
sys.argv will be
["manage.py", "delete-books", "--names", "test"], so
"test" will again be found, and the test-specific changes will accidentally be applied. This could backfire badly, so avoid this pattern.
Learn how to make your tests run quickly in my book Speed Up Your Django Tests.
One summary email a week, no spam, I pinky promise.
- Make Django Tests Always Rebuild the Database if It Exists
- How to Disallow Auto-named Django Migrations
- Django’s Field Choices Don’t Constrain Your Data
Tags: django, python