Как настроить Django для простой разработки и развертывания?

112

Я обычно использую SQLite при разработке Django , но на живом сервере часто требуется что-то более надежное (например, MySQL / PostgreSQL ). Неизменно, есть и другие изменения, которые нужно внести в настройки Django: разные места / интенсивность ведения журнала, пути к мультимедиа и т. Д.

Как вы управляете всеми этими изменениями, чтобы сделать развертывание простым автоматизированным процессом?

Питер Мортенсен
источник
Я не делаю ничего более необычного, чем кто-либо еще :). Я просто использую ORM, поставляемый django.
Эндрю Следж,
1
Вопрос был в том, как автоматизировать изменение настроек для переключения между средами :-)
Guruprasad
Вы можете взглянуть на этот пакет: django-split-settings
sobolevn

Ответы:

86

Обновление: был выпущен django-configurations , который, вероятно, для большинства людей лучше, чем делать это вручную.

Если вы предпочитаете делать что-то вручную, мой предыдущий ответ все еще применим:

У меня есть несколько файлов настроек.

  • settings_local.py - специфичная для хоста конфигурация, такая как имя базы данных, пути к файлам и т. д.
  • settings_development.py- конфигурация, используемая для разработки, например DEBUG = True.
  • settings_production.py- конфигурация, используемая для производства, например SERVER_EMAIL.

Я связываю все это вместе с settings.pyфайлом, который сначала импортирует settings_local.py, а затем один из двух других. Он решает, что загружать, двумя настройками внутри settings_local.py- DEVELOPMENT_HOSTSи PRODUCTION_HOSTS. settings.pyвызывает, platform.node()чтобы найти имя хоста компьютера, на котором он работает, а затем ищет это имя хоста в списках и загружает второй файл настроек в зависимости от того, в каком списке он находит имя хоста.

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

Посмотрите пример здесь .

Джим
источник
2
что, если постановка (разработка) и производство находятся на одной машине? platform.node () тогда возвращает то же самое.
gwaramadze 02
2
Ссылка на пример недоступна.
Jickson
Отличная идея определить настройки на основе списков хостов! Моя единственная придирка - это номенклатура (settings_local.py всегда импортируется первым, поэтому любые настройки, которые не переопределены, по-прежнему будут активны в производстве, что делает суффикс _localдовольно запутанным) и тот факт, что вы не используете модули (настройки /base.py, настройки / local.py, настройки / production.py). Также было бы разумно сохранить это в отдельном репозитории ... еще лучше, безопасный сервис, который обслуживает эту информацию из канонического источника (вероятно, избыточный для большинства) ... чтобы новый хост не требовал новой версии.
DylanYoung
Еще лучше, если вы используете программное обеспечение для управления машиной, вместо того, чтобы проверять список хостов в .pyфайле и, таким образом, предоставляя каждому хосту доступ к информации о конфигурации каждого другого хоста, вы можете создать шаблон manage.py для использования соответствующих настроек. файл в конфигурации развертывания.
DylanYoung
26

Лично я использую один файл settings.py для проекта, я просто ищу имя хоста, на котором он находится (имена хостов на моих машинах разработки начинаются с "gabriel", поэтому у меня есть только это:

import socket
if socket.gethostname().startswith('gabriel'):
    LIVEHOST = False
else: 
    LIVEHOST = True

то в других частях у меня есть такие вещи, как:

if LIVEHOST:
    DEBUG = False
    PREPEND_WWW = True
    MEDIA_URL = 'http://static1.grsites.com/'
else:
    DEBUG = True
    PREPEND_WWW = False
    MEDIA_URL = 'http://localhost:8000/static/'

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

Габриэль Росс
источник
Мне нравится эта идея, но она не позволяет мне различать разные экземпляры Django, работающие на одном хосте. Это могло бы произойти, например, если у вас были разные экземпляры, запущенные для разных поддоменов на одном и том же хосте.
Эрик
24

В конце settings.py у меня есть следующее:

try:
    from settings_local import *
except ImportError:
    pass

Таким образом, если я хочу переопределить настройки по умолчанию, мне нужно просто поместить settings_local.py прямо рядом с settings.py.

Дмитрий Шевченко
источник
4
Это немного опасно , потому что если опечатка в settings_localрезультатах в ImportErrorэто exceptпроглотит его молча.
Крис Мартин
Вы можете проверить сообщение No module named...vs cannot import name..., но оно хрупкое. Или поместите свой импорт в settings_local.py в блоки try и вызовите более конкретное исключение: MisconfiguredSettingsили что-то в этом роде.
DylanYoung
11

У меня есть два файла. settings_base.pyкоторый содержит общие / стандартные настройки и проверяется в системе управления версиями. У каждого развертывания есть отдельный settings.py, который выполняется from settings_base import *в начале, а затем переопределяется по мере необходимости.

Джон Милликин
источник
1
Я тоже этим пользуюсь. Он превосходит инверсию (dmishe "from settings_local import *" в конце settings.py), потому что позволяет локальным настройкам получать доступ и изменять глобальные, если это необходимо.
Карл Мейер,
3
В settings_local.pyэтом случае from settings import *он может переопределить значения в settings.py. ( settings_local.pyфайл необходимо импортировать в конце settings.py).
Сет,
В любом случае это можно сделать. Взгляните на stackoverflow.com/a/7047633/3124256 выше. @Seth Это рецепт циклического импорта.
DylanYoung
7

Самый простой способ, который я нашел, был:

1) используйте файл settings.py по умолчанию для локальной разработки и 2) создайте файл production-settings.py, начиная с:

import os
from settings import *

А затем просто переопределите настройки, которые отличаются в производстве:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}
Андре Боссар
источник
Как django узнает, что нужно загрузить производственные настройки?
AlxVallejo,
2

В некоторой степени это связано с проблемой развертывания самого Django с несколькими базами данных, вы можете взглянуть на Djangostack . Вы можете загрузить совершенно бесплатный установщик, который позволяет вам установить Apache, Python, Django и т. Д. В процессе установки мы позволяем вам выбрать, какую базу данных вы хотите использовать (MySQL, SQLite, PostgreSQL). Мы широко используем установщики при внутренней автоматизации развертываний (их можно запускать в автоматическом режиме).

Josue
источник
1
В качестве альтернативы я хотел бы порекомендовать Django Turnkey Linux на основе стека Ubuntu * NIX с предустановленным django.
jochem 02
1

У меня есть файл settings.py во внешнем каталоге. Таким образом, он не будет возвращен в систему контроля версий или перезаписан при развертывании. Я помещаю это в файл settings.py в моем проекте Django вместе с любыми настройками по умолчанию:

import sys
import os.path

def _load_settings(path):    
    print "Loading configuration from %s" % (path)
    if os.path.exists(path):
    settings = {}
    # execfile can't modify globals directly, so we will load them manually
    execfile(path, globals(), settings)
    for setting in settings:
        globals()[setting] = settings[setting]

_load_settings("/usr/local/conf/local_settings.py")

Примечание. Это очень опасно, если вы не можете доверять local_settings.py.

Чейз Зайберт
источник
1

В дополнение к нескольким файлам настроек, упомянутым Джимом, я также обычно помещаю две настройки в свой файл settings.py вверху BASE_DIRиBASE_URL устанавливаю путь к коду и URL-адрес базы сайта, все остальные настройки изменяются присоединиться к ним.

BASE_DIR = "/home/sean/myapp/" например MEDIA_ROOT = "%smedia/" % BASEDIR

Поэтому при перемещении проекта мне нужно только отредактировать эти настройки, а не искать по всему файлу.

Я также рекомендовал бы обратить внимание на Fabric и Capistrano (инструмент Ruby, но его можно использовать для развертывания приложений Django), которые упрощают автоматизацию удаленного развертывания.

Шон О Доннелл
источник
Ansible - это Python, и он предлагает гораздо более надежные средства подготовки, чем Fabric. Они тоже хорошо сочетаются.
DylanYoung
1

Ну, я использую такую ​​конфигурацию:

В конце settings.py:

#settings.py
try:
    from locale_settings import *
except ImportError:
    pass

И в locale_settings.py:

#locale_settings.py
class Settings(object):

    def __init__(self):
        import settings
        self.settings = settings

    def __getattr__(self, name):
        return getattr(self.settings, name)

settings = Settings()

INSTALLED_APPS = settings.INSTALLED_APPS + (
    'gunicorn',)

# Delete duplicate settings maybe not needed, but I prefer to do it.
del settings
del Settings
сакабуч
источник
1

Столько сложных ответов!

Каждый файл settings.py содержит:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Я использую этот каталог, чтобы установить переменную DEBUG следующим образом (замените директорию, где находится ваш код разработчика):

DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
    DEBUG = True

Затем каждый раз, когда файл settings.py перемещается, DEBUG будет иметь значение False, и это ваша производственная среда.

Каждый раз, когда вам нужны настройки, отличные от тех, что в вашей среде разработки, просто используйте:

if(DEBUG):
    #Debug setting
else:
    #Release setting
JM Desrosiers
источник
0

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

Ycros
источник
0

Я использую среду:

if os.environ.get('WEB_MODE', None) == 'production' :
   from settings_production import *
else :
   from settings_dev import *

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

Слашмили
источник
0

Это более старый пост, но я думаю, что если я добавлю это полезное, libraryэто упростит ситуацию.

Используйте django-configuration

Быстрый старт

pip install django-configurations

Затем подклассифицируйте включенный класс configurations.Configuration в файле settings.py вашего проекта или в любом другом модуле, который вы используете для хранения констант настроек, например:

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

Задайте для DJANGO_CONFIGURATIONпеременной среды имя только что созданного вами класса, например ~/.bashrc:

export DJANGO_CONFIGURATION=Dev

и DJANGO_SETTINGS_MODULEпеременную среды в путь импорта модуля, как обычно, например, в bash:

export DJANGO_SETTINGS_MODULE=mysite.settings

В качестве альтернативы поставить --configurationпараметр при использовании команд управления Django вдоль линий по умолчанию Джанго --settingsопции командной строки, например:

python manage.py runserver --settings=mysite.settings --configuration=Dev

Чтобы позволить Django использовать вашу конфигурацию, вам теперь нужно изменить ваш скрипт manage.py или wsgi.py, чтобы использовать версии соответствующих стартовых функций django-configurations , например, типичный manage.py с django-конфигурациями будет выглядеть так:

#!/usr/bin/env python

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

    from configurations.management import execute_from_command_line

    execute_from_command_line(sys.argv)

Обратите внимание, что в строке 10 мы не используем общий инструмент, django.core.management.execute_from_command_lineа вместо него configurations.management.execute_from_command_line.

То же самое относится к вашему wsgi.py файлу , например:

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

from configurations.wsgi import get_wsgi_application

application = get_wsgi_application()

Здесь мы не используем значение по умолчанию django.core.wsgi.get_wsgi_application функцию а вместо этого configurations.wsgi.get_wsgi_application.

Это оно! Теперь вы можете использовать свой проект с manage.py и вашим любимым сервером с поддержкой WSGI.

Маленький Филд
источник
-2

Фактически, вам, вероятно, следует подумать о том, чтобы иметь одинаковые (или почти одинаковые) конфигурации для вашей среды разработки и производства. В противном случае время от времени будут возникать ситуации типа «Эй, это работает на моей машине».

Поэтому, чтобы автоматизировать развертывание и устранить эти проблемы с WOMM, просто используйте Docker .

Дмитрий Михайлов
источник