Как узнать, работает ли мое приложение Django на сервере разработки или нет?

Как я могу быть уверен, что мое приложение работает на сервере разработки или нет? Я полагаю, я мог бы проверить значение settings.DEBUG и предположить, что если DEBUG равно True, то он работает на сервере разработки, но я бы предпочел знать наверняка, чем полагаться на соглашение.


person Imran    schedule 18.08.2009    source источник


Ответы (13)


server = request.META.get('wsgi.file_wrapper', None)
if server is not None and server.__module__ == 'django.core.servers.basehttp':
    print('inside dev')

Конечно, wsgi.file_wrapper может быть установлен на META и иметь класс из модуля с именем django.core.servers.basehttp по крайнему совпадению в другой серверной среде, но я надеюсь, что это вам поможет.

Кстати, я обнаружил это, создав синтаксически недопустимый шаблон во время работы на сервере разработки и искал интересные вещи в разделах Traceback и Request information, поэтому я просто редактирую свой ответ, чтобы подтвердить идеи Нейта.

person inerte    schedule 18.08.2009
comment
+1 за попытку решить вопрос, т. е. определить, какой сервер обслуживает приложение Django, а не полагаться на настройки. Например, ничто не мешает кому-то работать в режиме DEBUG за чем-то другим, кроме веб-сервера разработки. - person Ryan Duffield; 20.08.2009
comment
Еще одно поле META, специфичное для сервера разработки: SERVER_SOFTWARE имеет строки WSGIServer и Python для dev и все, что вы настраиваете на своем HTTP-сервере при развертывании. - person zgoda; 21.08.2009
comment
Я бы добавил getattr(server, '__module__', None) во вторую строку вместо того, чтобы сразу переходить к записи через точку. Ты никогда не узнаешь... - person Tal Weiss; 31.10.2010
comment
Очень круто, но хотелось бы делать это один раз при запуске, а не при каждом запросе. Это возможно? - person Tal Weiss; 31.10.2010
comment
@TalWeiss, вы можете добавить логику к manage.py и wsgi.py (или, сохраняя DRY, добавить логику в третий файл, например setvars.py, который импортируется и вызывается обоими). Поэтому используйте логику, подобную ответу выше, или другому из этих ответов, чтобы вызывать различные варианты os.environ.setdefault('DJANGO_SETTINGS_MODULE','some.settings.module'). Это предполагает, что вы разделяете свой модуль настроек на подмодули по среде. С другой стороны, ответ выше не будет работать, поскольку запрос еще не установлен. Но ты получил идею. - person driftcatcher; 31.10.2012
comment
В Django 1.5.5, работающем на OS X, имя модуля — wsgiref.util. Так что этот фрагмент не сработает. - person Rockallite; 17.12.2013
comment
в Django 1.8.12 в Linux имя модуля также wsgiref.util - person ckot; 04.05.2016

Я поместил следующее в свой settings.py, чтобы различать стандартный сервер разработки и производство:

import sys
RUNNING_DEVSERVER = (len(sys.argv) > 1 and sys.argv[1] == 'runserver')

Однако это также зависит от соглашения.

(Изменено в соответствии с комментарием Даниэля Магнуссона)

person Aryeh Leib Taurog    schedule 25.11.2010
comment
мне пришлось добавить if len(sys.argv) ›1: на сервер prod, чтобы он заработал. - person Daniel Magnusson; 03.10.2012
comment
Это лучший ответ, поскольку он не требует запроса. Я хочу сделать это, чтобы условно подключить URL-адреса мультимедиа - person Aaron McMillin; 19.05.2017
comment
Не могли бы вы объяснить, для чего это? Может я не понимаю проблемы, но эта переменная хранит, вызывается ли сайт с runserver'ом manage.py, да? И что вы с этим делаете? Я натыкаюсь на этот пост, и это кажется новым материалом, который я хочу изучить. Я искал способ определить, нахожусь ли я на локальном хосте, в этом случае включите DEBUG (я не ищу ответ об этом в этом сообщении) - person aless80; 07.03.2018
comment
@ aless80 есть вещи, специфичные для uwsgi, которые вы можете отключить при работе с dev-сервером, например спулер. - person BjornW; 26.09.2019
comment
упрощено здесь: stackoverflow.com/a/37880897 - person djvg; 26.11.2020

Обычно я устанавливаю переменную с именем environment и устанавливаю для нее значение «РАЗРАБОТКА», «ПОДГОТОВКА» или «ПРОИЗВОДСТВО». Затем в файле настроек я могу добавить базовую логику для изменения используемых настроек в зависимости от среды.

EDIT: Кроме того, вы можете просто использовать эту логику для включения различных settings.py файлов, которые переопределяют базовые настройки. Например:

if environment == "DEBUG":
    from debugsettings import *
person Soviut    schedule 18.08.2009

Обычно это работает:

import sys

if 'runserver' in sys.argv:
    # you use runserver
person Sven R. Kunze    schedule 17.06.2016

Полагаться на settings.DEBUG — это самый элегантный способ AFAICS, поскольку он также иногда используется в кодовой базе Django.

Я полагаю, что вам действительно нужен способ установить этот флаг автоматически, без необходимости обновлять его вручную каждый раз, когда вы загружаете проект на рабочие серверы.

Для этого я проверяю путь к settings.py (в settings.py), чтобы определить, на каком сервере работает проект:

if __file__ == "path to settings.py in my development machine":
    DEBUG = True
elif __file__ in [paths of production servers]:
    DEBUG = False
else:
    raise WhereTheHellIsThisServedException()

Имейте в виду, вы также можете предпочесть выполнять эту проверку с переменными среды, как предлагает @Soviut. Но для тех, кто разрабатывал в Windows и работал в Linux, проверить пути к файлам было намного проще, чем использовать переменные среды.

person utku_karatas    schedule 18.08.2009
comment
ну, за исключением случаев, когда я мог бы принять один и тот же путь в разработке и производстве (что победило бы это), это кажется мне лучшим. и +1 за WhereTheHellIsThisServedException :-) - person nemesisfixx; 01.04.2012

Я столкнулся с этой проблемой только сейчас и в итоге написал решение, подобное решению Арье Лейба Таурога. Мое главное отличие состоит в том, что я хочу различать производственную среду и среду разработки при запуске сервера, а также при запуске некоторых одноразовых сценариев для моего приложения (которые я запускаю как DJANGO_SETTINGS_MODULE=settings python [сценарий]). В этом случае недостаточно просто посмотреть, является ли argv[1] == runserver. Итак, что я придумал, так это передать дополнительный аргумент командной строки, когда я запускаю сервер разработки, а также когда я запускаю свои скрипты, и просто ищу этот аргумент в settings.py. Итак, код выглядит так:

if '--in-development' in sys.argv:
    ## YES! we're in dev
    pass
else:
    ## Nope, this is prod
    pass

затем запуск сервера django становится

python manage.py runserver [любые параметры, которые вы хотите] --in-development

и запускать мои сценарии так же просто, как

DJANGO_SETTINGS_MODULE=настройки python [myscript] --в разработке

Просто убедитесь, что дополнительный аргумент, который вы передаете, не конфликтует ни с чем django (на самом деле я использую имя своего приложения как часть аргумента). Я думаю, что это довольно прилично, так как позволяет мне точно контролировать, когда мой сервер и сценарии будут вести себя как prod или dev, и я не полагаюсь ни на какие другие соглашения, кроме своих собственных.

РЕДАКТИРОВАТЬ: manage.py жалуется, если вы передаете нераспознанные параметры, поэтому вам нужно изменить код в settings.py, чтобы он был чем-то вроде

if sys.argv[0] == 'manage.py' or '--in-development' in sys.argv:
    # ...
    pass

Хотя это работает, я понимаю, что это не самое элегантное решение...

person Luiz Scheidegger    schedule 17.01.2012

Если вы хотите автоматически переключать файлы настроек в зависимости от среды выполнения, вы можете просто использовать что-то, что отличается от среды, например.

from os import environ
if environ.get('_', ''): 
    print "This is dev - not Apache mod_wsgi"         
person Ed C    schedule 03.10.2012

settings.DEBUG может иметь значение True и работать под Apache или другим сервером, не предназначенным для разработки. Он все равно будет работать. Насколько я могу судить, в среде выполнения нет ничего, кроме изучения pid и сравнения с pid в ОС, которые дадут вам эту информацию.

person hughdbrown    schedule 18.08.2009

Я использую:

DEV_SERVERS = [
    'mymachine.local',
]

DEVELOPMENT = platform.node() in DEV_SERVERS

что требует внимания к тому, что возвращает .node() на ваших машинах. Важно, чтобы по умолчанию не было разработки, чтобы вы случайно не раскрыли конфиденциальную информацию о разработке.

Вы также можете изучить более сложные способы уникальной идентификации компьютеров. .

person Carl G    schedule 27.06.2012

Вы можете определить, используете ли вы WSGI (mod_wsgi, gunicorn, официантка и т. д.) или manage.py (runserver, test, migrate и т. д.) или что-то еще:

import sys
WSGI = 'django.core.wsgi' in sys.modules
person OrangeDog    schedule 02.02.2018

Одним из различий между средой разработки и развертывания будет сервер, на котором она работает. Что именно отличается, будет зависеть от вашей среды разработки и развертывания.

Зная свои собственные среды разработки и развертывания, можно использовать переменные HTTP-запроса, чтобы различать их. Посмотрите на переменные запроса, такие как request.META.HTTP_HOST, request.META.SERVER_NAME и request.META.SERVER_PORT, и сравните их. в двух средах.

Бьюсь об заклад, вы найдете что-то совершенно очевидное, что отличается и может быть использовано для обнаружения вашей среды разработки. Проведите тест в settings.py и установите переменную, которую вы можете использовать в другом месте.

person Nate    schedule 18.08.2009

Вдохновленный ответом Арье, трюк, который я придумал для себя, заключается в том, чтобы просто найти имя моего сценария управления в sys.argv[0]:

USING_DEV_SERVER = "pulpdist/manage_site.py" in sys.argv[0]

(Мой вариант использования — автоматическое включение собственной аутентификации Django при запуске тестового сервера — при работе под Apache, даже на серверах разработки, вся аутентификация для моего текущего проекта обрабатывается через Kerberos)

person ncoghlan    schedule 24.05.2012

Вы можете проверить значение request.META["SERVER_SOFTWARE"]:

dev_servers = ["WSGIServer", "Werkzeug"]
if any(server in request.META["SERVER_SOFTWARE"] for server in dev_servers):
    print("is local")
person mislavcimpersak    schedule 21.05.2019