Jak skonfigurować Django do prostego programowania i wdrażania?

112

Zwykle używam SQLite podczas tworzenia Django , ale na serwerze rzeczywistym często potrzebne jest coś solidniejszego ( MySQL / na przykład PostgreSQL ). Niezmiennie są też inne zmiany, które należy wprowadzić w ustawieniach Django: różne lokalizacje / intensywności rejestrowania, ścieżki mediów itp.

Jak zarządzasz wszystkimi tymi zmianami, aby wdrożenie było prostym, zautomatyzowanym procesem?

Peter Mortensen
źródło
Najwyraźniej nie robię nic tak wyszukanego jak ktokolwiek inny :). Po prostu korzystam z ORM, który dostarcza django.
Andrew Sledge
1
Pytanie brzmiało, jak zautomatyzować zmianę ustawień, aby przełączać się między środowiskami :-)
Guruprasad
Możesz
rzucić

Odpowiedzi:

86

Aktualizacja: wydano django-configuration , co jest prawdopodobnie lepszą opcją dla większości ludzi niż robienie tego ręcznie.

Jeśli wolisz robić rzeczy ręcznie, moja wcześniejsza odpowiedź nadal obowiązuje:

Mam wiele plików ustawień.

  • settings_local.py - konfiguracja specyficzna dla hosta, taka jak nazwa bazy danych, ścieżki plików itp.
  • settings_development.py- konfiguracja używana do rozwoju, np DEBUG = True.
  • settings_production.py- konfiguracja używana do produkcji, np SERVER_EMAIL.

Wiążę to wszystko razem z settings.pyplikiem, który najpierw importuje settings_local.py, a następnie jednym z dwóch pozostałych. Decyduje, które załadować za pomocą dwóch ustawień w środku settings_local.py- DEVELOPMENT_HOSTSi PRODUCTION_HOSTS. settings.pywezwaniaplatform.node() aby znaleźć nazwę hosta maszyny, na której działa, a następnie szuka tej nazwy hosta na listach i ładuje drugi plik ustawień w zależności od listy, na której znajduje nazwę hosta.

W ten sposób jedyną rzeczą, o którą naprawdę musisz się martwić, jest aktualizowanie settings_local.pypliku z konfiguracją specyficzną dla hosta, a wszystko inne jest obsługiwane automatycznie.

Zobacz przykład tutaj .

Jim
źródło
2
co się stanie, jeśli etapowanie (rozwój) i produkcja są na tym samym komputerze? platforma.node () zwraca wtedy to samo.
gwaramadze
2
Przykładowy link nie działa.
Jickson,
Świetny pomysł na ustalenie ustawień na podstawie list hostów! Moim jedynym chwytem jest nomenklatura (settings_local.py jest zawsze importowane jako pierwsze, więc wszelkie ustawienia, które nie są nadpisane, nadal będą aktywne w produkcji, co sprawia, że ​​sufiks jest _localraczej mylący) oraz fakt, że nie używasz modułów (ustawienia /base.py, settings / local.py, settings / production.py). Byłoby również rozsądne, aby przechowywać to w oddzielnym repozytorium ... jeszcze lepiej, bezpiecznej usłudze, która obsługuje te informacje z kanonicznego źródła (prawdopodobnie dla większości przesada) ... aby nowy host nie wymagał nowej wersji.
DylanYoung
Nawet lepiej, jeśli używasz oprogramowania do zarządzania komputerami, zamiast sprawdzać listę hostów w .pypliku, a tym samym dawać każdemu hostowi dostęp do informacji o konfiguracji każdego innego hosta, możesz utworzyć szablon manage.py tak, aby używał odpowiednich ustawień plik w konfiguracjach wdrożenia.
DylanYoung
26

Osobiście używam pojedynczego pliku settings.py dla projektu, po prostu sprawdzam nazwę hosta, na którym się znajduje (moje maszyny deweloperskie mają nazwy hostów zaczynające się od „gabriel”, więc mam tylko to:

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

to w innych częściach mam takie rzeczy jak:

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/'

i tak dalej. Trochę mniej czytelny, ale działa dobrze i oszczędza konieczności żonglowania wieloma plikami ustawień.

Gabriel Ross
źródło
Podoba mi się ten pomysł, ale nie pozwala mi na rozróżnienie między różnymi instancjami Django działającymi na tym samym hoście. Może się to zdarzyć na przykład, jeśli masz różne instancje działające dla różnych subdomen na tym samym hoście.
Erik,
24

Na końcu settings.py mam:

try:
    from settings_local import *
except ImportError:
    pass

W ten sposób, jeśli chcę zmienić ustawienia domyślne, muszę po prostu umieścić settings_local.py tuż obok settings.py.

Dmitrij Szewczenko
źródło
4
Jest to nieco niebezpieczne, ponieważ jeśli to literówka w settings_localPowoduje to ImportError, to exceptbędzie ją połknąć w milczeniu.
Chris Martin
Możesz sprawdzić wiadomość No module named...vs cannot import name..., ale jest krucha. Lub umieść import w settings_local.py w blokach try i zgłoś bardziej szczegółowy wyjątek: MisconfiguredSettingslub coś w tym stylu.
DylanYoung
11

Mam dwa pliki. settings_base.pyktóry zawiera ustawienia wspólne / domyślne i który jest sprawdzany w kontroli źródła. Każde wdrożenie ma oddzielne settings.py, które jest wykonywane from settings_base import *na początku, a następnie w razie potrzeby zastępuje.

John Millikin
źródło
1
Ja też tego używam. Jest lepszy od odwrotnego (dmishe's "from settings_local import *" na końcu settings.py), ponieważ pozwala lokalnym ustawieniom na dostęp i modyfikowanie ustawień globalnych, jeśli to konieczne.
Carl Meyer
3
Jeśli settings_local.pyto zrobi from settings import *, może zastąpić wartości w settings.py. ( settings_local.pyplik musi zostać zaimportowany na końcu settings.py).
Seth
Tak czy inaczej można to zrobić. Spójrz na stackoverflow.com/a/7047633/3124256 powyżej. @Seth To przepis na import okrężny.
DylanYoung
7

Najbardziej uproszczony sposób, jaki znalazłem, to:

1) użyj domyślnego settings.py do lokalnego programowania i 2) utwórz plik production-settings.py zaczynając od:

import os
from settings import *

A potem po prostu zastąp ustawienia, które różnią się w produkcji:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}
Andre Bossard
źródło
Skąd django wie, aby załadować ustawienia produkcyjne?
AlxVallejo
2

Nieco powiązane, jeśli chodzi o kwestię wdrażania samego Django z wieloma bazami danych, możesz rzucić okiem na Djangostack . Możesz pobrać całkowicie darmowy instalator, który pozwala zainstalować Apache, Python, Django itp. W ramach procesu instalacji umożliwiamy Ci wybór bazy danych, której chcesz używać (MySQL, SQLite, PostgreSQL). Używamy instalatorów w szerokim zakresie podczas wewnętrznej automatyzacji wdrożeń (mogą one działać w trybie nienadzorowanym).

Josue
źródło
1
Alternatywnie chciałbym polecić Django Turnkey Linux oparty na stosie Ubuntu * NIX z preinstalowanym django.
jochem
1

Mam plik settings.py w katalogu zewnętrznym. W ten sposób nie zostanie wpisany do kontroli źródła ani nadpisany przez wdrożenie. Umieściłem to w pliku settings.py w moim projekcie Django, wraz z wszelkimi ustawieniami domyślnymi:

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")

Uwaga: jest to bardzo niebezpieczne, jeśli nie możesz ufać local_settings.py.

Ścigaj Seiberta
źródło
1

Oprócz wielu plików ustawień wspomnianych przez Jima, staram się również umieszczać dwa ustawienia w moim pliku settings.py u góry BASE_DIRi BASE_URLustawić ścieżkę kodu i adres URL do podstawy witryny, wszystkie inne ustawienia są modyfikowane dołączać się do nich.

BASE_DIR = "/home/sean/myapp/" na przykład MEDIA_ROOT = "%smedia/" % BASEDIR

Więc przenosząc projekt muszę tylko edytować te ustawienia i nie przeszukiwać całego pliku.

Poleciłbym również przyjrzeć się fabric i Capistrano (narzędziu Ruby, ale może być używane do wdrażania aplikacji Django), które ułatwiają automatyzację zdalnego wdrażania.

Sean O Donnell
źródło
Ansible to Python i oferuje znacznie bardziej niezawodne narzędzia do obsługi administracyjnej niż Fabric. Ładnie się łączą.
DylanYoung
1

Cóż, używam tej konfiguracji:

Na końcu settings.py:

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

A w 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
sacabuche
źródło
1

Tyle skomplikowanych odpowiedzi!

Każdy plik settings.py zawiera:

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

Używam tego katalogu, aby ustawić zmienną DEBUG w ten sposób (ponownie wstaw z Directoy, w którym znajduje się twój kod dev):

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

Następnie za każdym razem, gdy plik settings.py zostanie przeniesiony, DEBUG będzie miał wartość False i będzie to Twoje środowisko produkcyjne.

Za każdym razem, gdy potrzebujesz innych ustawień niż te w środowisku deweloperskim, po prostu użyj:

if(DEBUG):
    #Debug setting
else:
    #Release setting
JM Desrosiers
źródło
0

Myślę, że to zależy od rozmiaru witryny, czy musisz przyspieszyć korzystanie z SQLite. Z powodzeniem użyłem SQLite na kilku mniejszych aktywnych witrynach i działa świetnie.

Ycros
źródło
0

Używam środowiska:

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

Uważam, że jest to znacznie lepsze podejście, ponieważ ostatecznie potrzebujesz specjalnych ustawień dla swojego środowiska testowego i możesz łatwo dodać je do tego warunku.

slashmili
źródło
0

To jest starszy post, ale myślę, że jeśli dodam ten użyteczny, libraryto uprości sprawę.

Użyj konfiguracji django

Szybki start

pip install django-configurations

Następnie podklasuj dołączone konfiguracje.Klasa konfiguracji w pliku settings.py Twojego projektu lub innym module, którego używasz do przechowywania stałych ustawień, np .:

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

Ustaw DJANGO_CONFIGURATIONzmienną środowiskową na nazwę właśnie utworzonej klasy, np. W ~/.bashrc:

export DJANGO_CONFIGURATION=Dev

i DJANGO_SETTINGS_MODULEzmienną środowiskową do ścieżki importu modułu jak zwykle, np. w bash:

export DJANGO_SETTINGS_MODULE=mysite.settings

Alternatywnie podaj --configurationopcję podczas używania poleceń zarządzania Django zgodnie z domyślną --settingsopcją wiersza poleceń Django , np .:

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

Aby umożliwić Django korzystanie z Twojej konfiguracji, musisz teraz zmodyfikować skrypt manage.py lub wsgi.py, aby używał wersji odpowiednich funkcji startowych django-configuration , np. Typowy manage.py używający konfiguracji django wyglądałby następująco:

#!/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)

Zauważ, że w linii 10 nie używamy zwykłego narzędzia, django.core.management.execute_from_command_lineale zamiast tego configurations.management.execute_from_command_line.

To samo dotyczy twojego pliku wsgi.py , np:

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()

Tutaj nie używamy domyślnej django.core.wsgi.get_wsgi_applicationfunkcji, ale zamiast tego configurations.wsgi.get_wsgi_application.

Otóż ​​to! Możesz teraz używać swojego projektu z manage.py i ulubionym serwerem obsługującym WSGI.

Mały Phild
źródło
-2

W rzeczywistości prawdopodobnie powinieneś rozważyć posiadanie takich samych (lub prawie takich samych) konfiguracji dla środowiska programistycznego i produkcyjnego. W przeciwnym razie od czasu do czasu będą się zdarzać sytuacje typu „Hej, to działa na moim komputerze”.

Aby więc zautomatyzować wdrażanie i wyeliminować problemy z WOMM, po prostu użyj Dockera .

Dmitrii Michajłow
źródło