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?


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 .


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ń.


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.


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.


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': {
           ....
    }
}

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


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.


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.


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

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

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.


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.


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.


-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 .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.