How can I be certain that my application is running on development server or not? I suppose I could check value of settings.DEBUG
and assume if DEBUG
is True
then it's running on development server, but I'd prefer to know for sure than relying on convention.

- 87,203
- 23
- 98
- 131
-
Old ones are good ones! One reason you may need this is that logging.handlers.RotatingFileHandler doesn't work on the development server, so you need to conditionalize LOGGING if you want to use it. – nigel222 Mar 31 '23 at 15:42
15 Answers
I put the following in my settings.py to distinguish between the standard dev server and production:
import sys
RUNNING_DEVSERVER = (len(sys.argv) > 1 and sys.argv[1] == 'runserver')
This also relies on convention, however.
(Amended per Daniel Magnusson's comment)

- 5,370
- 1
- 42
- 49
-
7i had to add if len(sys.argv) >1: on prod server to get it working. – Daniel Magnusson Oct 03 '12 at 09:39
-
This is the better answer since it doesn't require a request. I want to do this to conditionally wire up the media urls – Aaron McMillin May 19 '17 at 19:53
-
1Could you explain what is this for? Maybe I do not understand the problem, but this variable stores whether the site is called with manage.py runserver, right? And what do you do with this? I stumble upon this post and this seems new stuff I want to learn. I was looking for a way to detect whether I am on localhost, in that case turn DEBUG on (I am not looking for an answer about this on this post) – aless80 Mar 07 '18 at 02:51
-
@aless80 there are uwsgi-specific stuff you might want to disable when running with the dev-server, like the spooler – BjornW Sep 26 '19 at 13:59
-
1
-
What about running migrations (or any other command) on dev server? In my case it tries to connect to the database with the prod server credentials. – martintrapp Sep 16 '21 at 17:07
server = request.META.get('wsgi.file_wrapper', None)
if server is not None and server.__module__ == 'django.core.servers.basehttp':
print('inside dev')
Of course, wsgi.file_wrapper
might be set on META, and have a class from a module named django.core.servers.basehttp
by extreme coincidence on another server environment, but I hope this will have you covered.
By the way, I discovered this by making a syntatically invalid template while running on the development server, and searched for interesting stuff on the Traceback
and the Request information
sections, so I'm just editing my answer to corroborate with Nate's ideas.
-
4+1 for actually trying to address the question i.e. detecting what server is serving up the Django app, rather than relying on settings. For example, there is nothing stopping someone from running in DEBUG mode behind something other than the development web server. – Ryan Duffield Aug 20 '09 at 17:58
-
Another META field that is specific for dev server: SERVER_SOFTWARE has strings `WSGIServer` and `Python` on dev and anything you configure in your HTTP server on "deployed". – zgoda Aug 21 '09 at 08:19
-
I would add a `getattr(server, '__module__', None)` in the second line instead of going directly to the dot notation. You never know... – Tal Weiss Oct 31 '10 at 06:10
-
1Very cool, but I would like to do this once upon startup, and not upon every request. Is that possible? – Tal Weiss Oct 31 '10 at 06:17
-
1@TalWeiss you can add logic to `manage.py` and `wsgi.py` (or keeping with DRY, add the logic to a third file like `setvars.py` that gets imported & called by both). So use logic like the answer above, or another one of these answers, in order to call different variations of `os.environ.setdefault('DJANGO_SETTINGS_MODULE','some.settings.module')`. This assumes you separate your settings module into submodules by environment. On second thought the answer above won't work there since request isn't set yet. But you get the idea. – floer32 Oct 31 '12 at 14:17
-
1In Django 1.5.5 running on OS X, the module name is `wsgiref.util`. So this snippet won't work. – Rockallite Dec 17 '13 at 01:51
-
1
Usually this works:
import sys
if 'runserver' in sys.argv:
# you use runserver

- 1,909
- 2
- 13
- 17
-
1What would be the case under production environment? Doesn't this mean that `./manage.py runserver` is run and not for example `./manage.py shell_plus` – shwz Sep 29 '21 at 08:35
-
2According to documentation, you should not use 'runserver' in a production setting. Just make sure DEBUG is used correctly; e.g. add safety nets and checks. – Sven R. Kunze Oct 20 '21 at 05:55
Typically I set a variable called environment
and set it to "DEVELOPMENT", "STAGING" or "PRODUCTION". Within the settings file I can then add basic logic to change which settings are being used, based on environment.
EDIT: Additionally, you can simply use this logic to include different settings.py
files that override the base settings. For example:
if environment == "DEBUG":
from debugsettings import *

- 88,194
- 49
- 192
- 260
Relying on settings.DEBUG is the most elegant way AFAICS as it is also used in Django code base on occasion.
I suppose what you really want is a way to set that flag automatically without needing you update it manually everytime you upload the project to production servers.
For that I check the path of settings.py (in settings.py) to determine what server the project is running on:
if __file__ == "path to settings.py in my development machine":
DEBUG = True
elif __file__ in [paths of production servers]:
DEBUG = False
else:
raise WhereTheHellIsThisServedException()
Mind you, you might also prefer doing this check with environment variables as @Soviut suggests. But as someone developing on Windows and serving on Linux checking the file paths was plain easier than going with environment variables.

- 6,163
- 4
- 40
- 52
-
1well, apart from occasions when i might adopt same path convention in development and production (which would defeat this), this seems to be the best for me. and +1 for `WhereTheHellIsThisServedException` :-) – JWL Apr 01 '12 at 09:02
You can determine whether you're running under WSGI
(mod_wsgi, gunicorn, waitress, etc.) vs. manage.py
(runserver, test, migrate, etc.) or anything else:
import sys
WSGI = 'django.core.wsgi' in sys.modules

- 36,653
- 12
- 122
- 207
I came across this problem just now, and ended up writing a solution similar to Aryeh Leib Taurog's. My main difference is that I want to differentiate between a production and dev environments when running the server, but also when running some one-off scripts for my app (which I run like DJANGO_SETTINGS_MODULE=settings python [the script] ). In this case, simply looking at whether argv[1] == runserver isn't enough. So what I came up with is to pass an extra command-line argument when I run the devserver, and also when I run my scripts, and just look for that argument in settings.py. So the code looks like this:
if '--in-development' in sys.argv:
## YES! we're in dev
pass
else:
## Nope, this is prod
pass
then, running the django server becomes
python manage.py runserver [whatever options you want] --in-development
and running my scripts is as easy as
DJANGO_SETTINGS_MODULE=settings python [myscript] --in-development
Just make sure the extra argument you pass along doens't conflict with anything django (in reality I use my app's name as part of the argument). I think this is pretty decent, as it lets me control exactly when my server and scripts will behave as prod or dev, and I'm not relying on anyone else's conventions, other than my own.
EDIT: manage.py complains if you pass unrecognized options, so you need to change the code in settings.py to be something like
if sys.argv[0] == 'manage.py' or '--in-development' in sys.argv:
# ...
pass
Although this works, I recognize it's not the most elegant of solutions...

- 788
- 5
- 12
I use:
DEV_SERVERS = [
'mymachine.local',
]
DEVELOPMENT = platform.node() in DEV_SERVERS
which requires paying attention to what is returned by .node()
on your machines. It's important that the default be non-development so that you don't accidentally expose sensitive development information.
You could also look into more complicated ways of uniquely identifying computers.

- 17,394
- 14
- 91
- 115
settings.DEBUG could be True and running under Apache or some other non-development server. It will still run. As far as I can tell, there is nothing in the run-time environment short of examining the pid and comparing to pids in the OS that will give you this information.

- 47,733
- 20
- 85
- 108
Inspired by Aryeh's answer, the trick I devised for my own use is to just look for the name of my management script in sys.argv[0]
:
USING_DEV_SERVER = "pulpdist/manage_site.py" in sys.argv[0]
(My use case is to automatically enable Django native authentication when running the test server - when running under Apache, even on development servers, all authentication for my current project is handled via Kerberos)

- 40,168
- 10
- 71
- 80
One difference between the development and deployment environment is going to be the server that it’s running on. What exactly is different will depend on your dev and deployment environments.
Knowing your own dev and deploy environments, the HTTP request variables could be used to distinguish between the two. Look at request variables like request.META.HTTP_HOST
, request.META.SERVER_NAME
and request.META.SERVER_PORT
and compare them in the two environments.
I bet you’ll find something quite obvious that’s different and can be used to detect your development environment. Do the test in settings.py
and set a variable that you can use elsewhere.

- 18,752
- 8
- 48
- 54
You could check request.META["SERVER_SOFTWARE"]
value:
dev_servers = ["WSGIServer", "Werkzeug"]
if any(server in request.META["SERVER_SOFTWARE"] for server in dev_servers):
print("is local")

- 2,880
- 1
- 27
- 30
Simple you may check the path you work on server. Something like:
import os
SERVER = True if os.path.exists('/var/www/your_project') else False

- 3,300
- 3
- 15
- 23
One approach is to create an environment variable on your dev machine such as RUNNING_IN_DEVELOPMENT = 1
. JetBrains, for example, lets you do this in the Configuration Dialog.
Then in settings.py you can do:
try:
running_in_development = os.getenv('RUNNING_IN_DEVELOPMENT')
DEBUG = True if running_in_development else False
except Exception as e:
DEBUG = False

- 4,818
- 8
- 51
- 96