Django: Geliştirme ve üretim ayarları nasıl yönetilir?


129

Temel bir uygulama geliştiriyorum. Şimdi dağıtım aşamasında hem yerel ayarlara hem de üretim ayarlarına ihtiyacım olduğu anlaşıldı.

Aşağıdakileri bilmek harika olur:

  • Geliştirme ve üretim ayarlarıyla en iyi nasıl başa çıkılacağı.
  • Django-debug-toolbar gibi uygulamaların yalnızca geliştirme ortamında nasıl saklanacağı.
  • Geliştirme ve dağıtım ayarları için diğer ipuçları ve en iyi uygulamalar.

Yanıtlar:


109

DJANGO_SETTINGS_MODULEOrtam değişkeni ayarları Django dosyasını kontrol yükleyecektir.

Bu nedenle, ilgili ortamlarınız için ayrı yapılandırma dosyaları oluşturursunuz (tabii ki bunların her ikisinin de import *ayrı bir "paylaşılan ayarlar" dosyasından yapılabileceğini unutmayın) ve DJANGO_SETTINGS_MODULEhangisinin kullanılacağını kontrol etmek için kullanın.

Bunu nasıl yapacağınız aşağıda açıklanmıştır:

Django belgelerinde belirtildiği gibi:

DJANGO_SETTINGS_MODULE değeri Python yolu sözdiziminde olmalıdır, örneğin mysite.settings. Ayarlar modülünün Python içe aktarma arama yolunda olması gerektiğini unutmayın.

Öyleyse, oluşturduğunuzu myapp/production_settings.pyve myapp/test_settings.pykaynak deponuzda olduğunu varsayalım .

Bu durumda, sırasıyla DJANGO_SETTINGS_MODULE=myapp.production_settingsbirincisini ve DJANGO_SETTINGS_MODULE=myapp.test_settingsikincisini kullanmayı ayarlarsınız .


Buradan sonra sorun, DJANGO_SETTINGS_MODULEortam değişkeninin ayarlanmasına dayanır .

DJANGO_SETTINGS_MODULEKomut dosyası veya kabuk kullanarak ayarlama

Daha sonra doğru ayarları yüklemek için (ortamı ayarlayarak) bir önyükleme betiği veya işlem yöneticisi kullanabilir veya Django: 'yu başlatmadan önce kabuğunuzdan çalıştırabilirsiniz export DJANGO_SETTINGS_MODULE=myapp.production_settings.

Bu dışa aktarımı herhangi bir zamanda bir kabuktan çalıştırabileceğinizi unutmayın - sizin .bashrcveya herhangi bir şeyin içinde yaşaması gerekmez .

DJANGO_SETTINGS_MODULEİşlem Yöneticisi kullanarak ayarlama

Ortamı ayarlayan bir önyükleme betiği yazmaktan hoşlanmıyorsanız (ve bu şekilde hissetmek için çok iyi nedenler var!), Bir işlem yöneticisi kullanmanızı tavsiye ederim:


Son olarak, not bunu yapabilirsiniz yararlanmak PYTHONPATH(saklayarak, bir üretim sunucusuna örneğin bambaşka bir yerde ayarları saklamak için değişken /etc/). Bu, yapılandırmanın uygulama dosyalarından ayrılmasına izin verir. Bunu isteyebilir veya istemeyebilirsiniz, bu uygulamanızın nasıl yapılandırıldığına bağlıdır.


7
Açıklığa kavuşturmak gerekirse, settings.pydosya SiteName/settings.pyvarsayılan olarak saklandığından , alternatif ayar dosyalarınızı aynı dizine yerleştirirseniz, bin / activ'e eklenen satırın okunması gerekir DJANGO_SETTINGS_MODULE="SiteName.test_settings"Aksi takdirde mükemmel yanıt!
alexbhandari

2
Tesadüfen, bunu adım adım nasıl yapacağınıza dair bir öğretici biliyor musunuz, Django'da yeniyim ve DJANGO_SETTINGS_MODULE veya PYTHONPATH'ı nerede ayarlayacağımı bilmiyorum
Jesus Almaral - Hackaprende

Bu çözüm bir conda env için geçerli görünmüyor. Conda env'de bin / activ yok.
Pouya Yousefi

1
@PouyaYousefi: Bu cevabı kullanmak için kesinlikle virtualenv kullanmanıza gerek yok . Cevap gerçekten iki adıma indirgeniyor: a) ayrı ayar dosyaları kullanın ve b) kullanmak DJANGO_SETTINGS_MODULEistediğinizi seçmek için kullanın. Değişiklik bin/activate yapmak ikincisini yapmaktır (TBH, bunun zaten iyi bir fikir olduğunu artık düşünmüyorum, bu yüzden onu çıkardım), ama tek olan bu değil.
Thomas Orozco

Ayrıca Django'yu pycharm topluluk sürümünde kullanıyorsanız ve hem komut satırında hem de pycharm topluluğunda birim testlerini doğru şekilde çalıştırmanız gerekiyorsa yararlıdır. Kaynak deponuzda myapp / settings.py'de yalnızca bir basit yapılandırma dosyası oluşturduğunuzu varsayın. Bu durumda, RUN / Edit Configuration / Environment değişkenindeki "DJANGO_SETTINGS_MODULE = myapp.settings" öğesini test durumlarını çalıştırmak için kullanmak üzere ayarlarsınız.
F.Tamy

58

Varsayılan olarak üretim ayarlarını kullanın, ancak dosyanızla settings_dev.pyaynı klasörde adlı bir dosya oluşturun settings.py. Orada gibi geçersiz kılmalar ekleyin DEBUG=True.

Geliştirme için kullanılacak bilgisayarda bunu ~/.bashrcdosyanıza ekleyin :

export DJANGO_DEVELOPMENT=true

settings.pyDosyanızın altına aşağıdakileri ekleyin.

# Override production variables if DJANGO_DEVELOPMENT env variable is set
if os.environ.get('DJANGO_DEVELOPMENT'):
    from settings_dev import *  # or specific overrides

( *Python'da içe aktarmanın genellikle önlenmesi gerektiğini unutmayın )

Varsayılan olarak, üretim sunucuları hiçbir şeyi geçersiz kılmayacaktır. Bitti!

Diğer cevaplarla karşılaştırıldığında, bu daha basittir çünkü güncelleme gerektirmez PYTHONPATHveya DJANGO_SETTINGS_MODULEbir seferde yalnızca bir django projesi üzerinde çalışmanıza izin veren bir ayar gerektirir .


8
bu nasıl doğru cevap değil? SO bugünlerde gerçekten bir karmaşa. Ty cs01
codyc4321

if os.environ.get('DJANGO_DEVELOPMENT', 'true')ayrıca çalışır. Bunu sadece yukarıdaki is not trueyöntem Python 3.6'da benim için içe aktarılamadığı için söylüyorum.
brt

1
@brt bu kötü bir fikir: her zaman DEVayarlarınızı kullanacak ve bu da özel verileri genel bir sunucuya sızdıracaktır . Gerçekten sadece DJANGO_DEVELOPMENTortam değişkeninin var olup olmadığını kontrol etmek istiyorsunuz (yani is not None).
cs01

Bilgi için teşekkürler, @ cs01. Yanlış ayarların yüklenmesiyle sitemi patlattığımda yanlış bir şey yaptığımı fark ettim, ancak settings_dev.pysunucuya neden yüklendiğinden emin değildim .
brt

2
@ cs01 Sadece is not Noneçeki bırakarak var olduğundan ve doğru olduğundan emin olmak için çok ileri giderdim . Ayrıca os.getenvkısaltma
Tjorriemorrie

35

Genellikle ortam başına bir ayar dosyam ve paylaşılan bir ayarlar dosyam var:

/myproject/
  settings.production.py
  settings.development.py
  shared_settings.py

Ortam dosyalarımın her birinde şunlar bulunur:

try:
    from shared_settings import *
except ImportError:
    pass

Bu, gerekirse paylaşılan ayarları geçersiz kılmama izin veriyor (değişiklikleri bu stanza'nın altına ekleyerek).

Daha sonra hangi ayar dosyalarının kullanılacağını settings.py ile ilişkilendirerek seçiyorum:

ln -s settings.development.py settings.py

2
Pep8 yasağı ile nasıl başa çıkıyorsunuz import *? Bu çeki devre dışı bırakır mısınız? Bu içe aktarmayı bir içine sardım exec()ama sonra bu dosyada tanımlanmamış değişkenler üzerinde koşullara sahip olamıyorum ve değişkeni INSTALLED_APPS"tanımsız" olduğu için değiştiremem
Mikhail

11
Ayar dosyalarımızı bırakmıyoruz, çünkü bunlar Python'da ifade edilen konfigürasyondan çok kod değiller.
Daniel Watkins

17

Bunu 6 kolay adımda böyle yaparım:

  1. Proje dizininizde bir klasör oluşturun ve adlandırın settings.

    Proje yapısı:

    myproject/
           myapp1/
           myapp2/              
           myproject/
                  settings/
  2. İç dört piton dosyaları oluşturun settingsdizinde yani __init__.py, base.py, dev.pyveprod.py

    Ayarlar dosyaları:

    settings/
         __init__.py
         base.py
         prod.py
         dev.py 
  3. Açın __init__.pyve aşağıdaki içerikle doldurun:

    init .py:

    from .base import *
    # you need to set "myproject = 'prod'" as an environment variable
    # in your OS (on which your website is hosted)
    if os.environ['myproject'] == 'prod':
       from .prod import *
    else:
       from .dev import *
  4. Açın base.pyve tüm ortak ayarlarla (hem üretimde hem de geliştirmede kullanılacak) doldurun. Örneğin:

    base.py:

    import os
    ...
    INSTALLED_APPS = [...]
    MIDDLEWARE = [...]
    TEMPLATES = [{...}]
    ...
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    MEDIA_ROOT = os.path.join(BASE_DIR, '/path/')
    MEDIA_URL = '/path/'
  5. dev.pyÖrneğin gelişime özgü olan şeyleri açın ve dahil edin:

    dev.py:

    DEBUG = True
    ALLOWED_HOSTS = ['localhost']
    ...
  6. prod.pyÖrneğin üretime özgü olan şeyleri açın ve dahil edin:

    prod.py:

    DEBUG = False
    ALLOWED_HOSTS = ['www.example.com']
    LOGGING = [...]
    ...

10

settings*.pyOrtam başına değişmesi gereken değişkenleri tahmin ederek birden çok dosya oluşturun . Sonra ana settings.pydosyanızın sonunda :

try:
  from settings_dev import *
except ImportError:
  pass

settings_*Her aşama için ayrı dosyalar tutarsınız .

settings_dev.pyDosyanızın en üstüne şunu ekleyin:

import sys
globals().update(vars(sys.modules['settings']))

Değiştirmeniz gereken değişkenleri içe aktarmak için.

Bu wiki girişi , ayarlarınızı nasıl böleceğiniz hakkında daha fazla fikir içerir.


Teşekkürler Burham! Uygulamayı dağıtırken, dağıtım ayarlarımı çalışırken görmek için yalnızca settings_dev dosyasını kaldırmam gerekir mi?
Kristian Roebuck

Evet veya ithalat yerinesettings_prod.py
Burhan Khalid

1
Bir dağıtımdaki ana settings.py dosyasını düzenlemek, sürüm kontrolüyle çakışacağı anlamına gelir, bu nedenle ileriye dönük en iyi yol bu olmayabilir. Thomas Orozco'nun seçeneğinin en iyisi olduğunu söyleyebilirim - DJANGO_SETTINGS_MODULE'u virtualenv postactivate betiğinizde veya gunicorn veya mod_wsgi kurulumunuzda ayarlayabilirsiniz
Steve Jalim

1
Sahneye özgü dosyaları asla kaynağa eklemediğinizden belki de bahsetmek gerekir. Bir projenin belirli bir aşamasına özgü ayarları zorlamayacağınızın anlaşıldığını varsaydım.
Burhan Halid

Virtualenv kullanıyorsanız, genellikle varsayılan olarak {{project_name}}. Ayarlarına döner. Yani 'ayarlar' sys.modules'de bir anahtar olmayacaktır. Bu, 'myproject.settings' (veya proje adınız ne olursa olsun) olacaktır. modname = "%s.settings" % ".".join(__name__.split('.')[:-1])Tam modül adını almak için kullanabilirsiniz ve sonra globals().update(vars(sys.modules[modname])). Bunun benim için iyi sonuç verdiğini görüyorum. Elbette modül adını bir dizge lehine programlama yoluyla belirleme hakkındaki biti atlamak çoğu durumda da muhtemelen işe yarayacaktır.
Eric

9

Harika django konfigürasyonlarını kullanıyorum ve tüm ayarlar şurada saklanıyor settings.py:

from configurations import Configuration

class Base(Configuration):
    # all the base settings here...
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    ...

class Develop(Base):
    # development settings here...
    DEBUG = True 
    ...

class Production(Base):
    # production settings here...
    DEBUG = False

Django projesini yapılandırmak için belgeleri takip ettim .


7

İşte kullandığımız yaklaşım:

  • bir settingsokunabilirlik için ayarları birden çok dosyaya ayıran modül;
  • bir .env.jsongit depomuzdan dışlanmasını istediğimiz veya ortama özgü kimlik bilgilerini ve parametreleri depolamak için dosya;
  • env.pyokumak için bir dosya.env.json dosyayı

Aşağıdaki yapıyı göz önünde bulundurarak:

...
.env.json           # the file containing all specific credentials and parameters
.gitignore          # the .gitignore file to exclude `.env.json`
project_name/       # project dir (the one which django-admin.py creates)
  accounts/         # project's apps
    __init__.py
    ...
  ...
  env.py            # the file to load credentials
  settings/
    __init__.py     # main settings file
    database.py     # database conf
    storage.py      # storage conf
    ...
venv                # virtualenv
...

Beğeniyle .env.json:

{
    "debug": false,
    "allowed_hosts": ["mydomain.com"],
    "django_secret_key": "my_very_long_secret_key",
    "db_password": "my_db_password",
    "db_name": "my_db_name",
    "db_user": "my_db_user",
    "db_host": "my_db_host",
}

Ve project_name/env.py:

<!-- language: lang-python -->
import json
import os


def get_credentials():
    env_file_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    with open(os.path.join(env_file_dir, '.env.json'), 'r') as f:
        creds = json.loads(f.read())
    return creds


credentials = get_credentials()

Aşağıdaki ayarlara sahip olabiliriz:

<!-- language: lang-py -->
# project_name/settings/__init__.py
from project_name.env import credentials
from project_name.settings.database import *
from project_name.settings.storage import *
...

SECRET_KEY = credentials.get('django_secret_key')

DEBUG = credentials.get('debug')

ALLOWED_HOSTS = credentials.get('allowed_hosts', [])

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    ...
]

if DEBUG:
    INSTALLED_APPS += ['debug_toolbar']

...

# project_name/settings/database.py
from project_name.env import credentials

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': credentials.get('db_name', ''),
        'USER': credentials.get('db_user', ''),
        'HOST': credentials.get('db_host', ''),
        'PASSWORD': credentials.get('db_password', ''),
        'PORT': '5432',
    }
}

bu çözümün faydaları şunlardır:

  • kullanıcıya özel kimlik bilgileri ve yapılandırmalargit deposunu değiştirmeden yerel geliştirme için ;
  • ortama özel yapılandırma , örneğin üç farklı ortama sahip üç farklı ortama sahip olabilirsiniz..env.json dev, aşamalı çalışma ve üretim gibi ;
  • kimlik bilgileri havuzda değil

Umarım bu yardımcı olur, bu çözümle ilgili herhangi bir uyarı görürseniz bize bildirin.


nerede varsayarak envile değiştirmektir dev, prodvb? Eski settings.pydosyaya ne giriyor ? İçinde ne var storage.pyve database.py?
dbinott

Merhaba @dbinott, env.pyhangi dosyanın yükleneceğini bir ortam değişkeniyle seçebilmeniz için dosyayı kolayca güncelleyebilirsiniz
Charlesthk

Örneğin: conf = os.environ.get ('CONF', '') file_ = f ".env. {Conf} .json"
Charlesthk

Yerel bir python veri türünün aksine neden json yapasınız?
hava saldırısı

4

Aşağıdaki dosya yapısını kullanıyorum:

project/
   ...
   settings/
   settings/common.py
   settings/local.py
   settings/prod.py
   settings/__init__.py -> local.py

Öyleyse __init__.pybir bağlantı (unix'te veya pencerelerde mklink) için local.pyveya olabilir, prod.pyböylece yapılandırma hala project.settingsmodülde temiz ve organize olur ve belirli bir yapılandırmayı kullanmak istiyorsanız ortam değişkenini DJANGO_SETTINGS_MODULEkullanarakproject.settings.prod ihtiyacınız olursa üretim ortamı için bir komut çalıştırmak.

Dosyalarda prod.pyve local.py:

from .shared import *

DATABASE = {
    ...
}

ve shared.pydosya belirli yapılandırmalar olmadan global olarak kalır.


3

cs01'in cevabından yola çıkarak:

ortam değişkeniyle sorun yaşıyorsanız, değerini bir dizeye ayarlayın (ör. DJANGO_DEVELOPMENT="true" ).

Ayrıca cs01'in dosya iş akışını şu şekilde değiştirdim:

#settings.py
import os
if os.environ.get('DJANGO_DEVELOPMENT') is not None:
    from settings_dev import * 
else:
    from settings_production import *
#settings_dev.py
development settings go here
#settings_production.py
production settings go here

Bu şekilde, Django'nun uygun ayarlar dosyasını çalıştırmadan önce bir ayarlar dosyasının tamamını okuması gerekmez. Bu çözüm, üretim dosyanız yalnızca üretim sunucunuzda bulunan şeylere ihtiyaç duyuyorsa kullanışlı olur.

Not: Python 3'te, içe aktarılan dosyaların eklenmesi gerekir .(örn. from .settings_dev import *)


1

1 ayar dosyasını saklamak istiyorsanız ve geliştirme işletim sisteminiz üretim işletim sisteminizden farklıysa, bunu ayarlarınızın altına koyabilirsiniz.py:

from sys import platform
if platform == "linux" or platform == "linux2":
    # linux
    # some special setting here for when I'm on my prod server
elif platform == "darwin":
    # OS X
    # some special setting here for when I'm developing on my mac
elif platform == "win32":
    # Windows...
    # some special setting here for when I'm developing on my pc

Daha fazlasını okuyun: Python'da işletim sistemini nasıl kontrol ederim?


1

Bu yanıtlanmış gibi görünüyor, ancak sürüm kontrolü ile birlikte kullandığım bir yöntem şu:

.Gitignore'a eklediğim yerel geliştirme ortamımdaki ayarlarla aynı dizinde bir env.py dosyası kurun:

env.py:

#!usr/bin/python

DJANGO_ENV = True
ALLOWED_HOSTS = ['127.0.0.1', 'dev.mywebsite.com']

.gitignore:

mywebsite/env.py

settings.py:

if os.path.exists(os.getcwd() + '/env.py'):
    #env.py is excluded using the .gitignore file - when moving to production we can automatically set debug mode to off:
    from env import *
else:
    DJANGO_ENV = False

DEBUG = DJANGO_ENV

Bunun işe yaradığını ve çok daha zarif olduğunu görüyorum - env.py ile yerel ortam değişkenlerimizi görmek kolay ve tüm bunları birden fazla settings.py dosyası veya benzeri olmadan halledebiliriz. Bu yöntemler, üretim sunucumuzda ayarlanmasını istemediğimiz her tür yerel ortam değişkeninin kullanılmasına izin verir. .Gitignore'u sürüm kontrolü aracılığıyla kullanarak, her şeyi sorunsuz bir şekilde entegre ediyoruz.


En basit çözüm. Bir dosya içinde bir Configsınıftaki her şeyi de tanımlayabiliriz env.py. Daha sonra bir yerine import *, modül tarafından içe aktarılabilir from env import Config. Bu şekilde, bunu kullanmanıza gerek kalmaz os.path, bu da her şeyi daha basit hale getirir.
Siddharth Pant

0

settings.pyÜretim için kullanın . Aynı dizinde settings_dev.pygeçersiz kılmalar için oluşturun .

# settings_dev.py

from .settings import * 

DEBUG = False

Bir geliştirme makinesinde Django uygulamanızı şununla çalıştırın:

DJANGO_SETTINGS_MODULE=<your_app_name>.settings_dev python3 manage.py runserver

Bir prod makinesinde, sanki elinizde settings.pyve başka hiçbir şeyiniz yokmuş gibi çalıştırın .

AVANTAJLARI

  1. settings.py (üretim için kullanılır), başka herhangi bir ortamın var olduğu gerçeğinden tamamen habersizdir.
  2. Üretim ve geliştirme arasındaki farkı görmek için tek bir konuma bakmanız yeterlidir - settings_dev.py. Yapılandırmaları toplamak gerek yok dağılmış settings_prod.py, settings_dev.pyvesettings_shared.py .
  3. Bir üretim sorununu giderdikten sonra bir kişi prod yapılandırmanıza bir ayar eklerse, bunun geliştirici yapılandırmanızda da görüneceğinden emin olabilirsiniz (açıkça geçersiz kılınmadıkça). Böylece farklı yapılandırma dosyaları arasındaki farklılık en aza indirilecektir.

0

Dosyaları ayarlama sorunu için, kopyalamayı seçiyorum

Project
   |---__init__.py   [ write code to copy setting file from subdir to current dir]
   |---settings.py  (do not commit this file to git)
   |---setting1_dir
   |         |--  settings.py
   |---setting2_dir
   |         |--  settings.py

Django'yu çalıştırdığınızda __init__py çalıştırılacaktır. Şu anda settings.py in setting1_dirdeğiştirileceksettings.py in Project .

Farklı ortam nasıl seçilir?

  • Değiştirme __init__.pydoğrudan .
  • değiştirmek için bir bash dosyası yapın __init__.py .
  • linux'ta env'i değiştirin ve sonra __init__.pybu değişkeni okuyalım.

Neden bu şekilde kullanıyorsunuz?

Aynı dizindeki çok fazla dosyayı sevmediğim için, çok fazla dosya diğer ortakların kafasını karıştıracak ve IDE için pek iyi olmayacak. (IDE hangi dosyayı kullandığımızı bulamıyor)

Tüm bu detayları görmek istemiyorsanız projeyi ikiye ayırabilirsiniz.

  1. Spring Initializr gibi küçük aracınızı sadece projenizi kurmak için yapın. (dosyayı kopyalamak gibi yapın)
  2. proje kodunuz

0

Google bulut uygulama motorundaki ortamlar arasında yapılandırmayı değiştirmek için farklı app.yaml dosyası kullanıyorum.

Terminal komutunuzda bir proxy bağlantısı oluşturmak için bunu kullanabilirsiniz:

./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:1433

https://cloud.google.com/sql/docs/sqlserver/connect-admin-proxy#macos-64-bit

Dosya: app.yaml

# [START django_app]
service: development
runtime: python37

env_variables:
  DJANGO_DB_HOST: '/cloudsql/myproject:myregion:myinstance'
  DJANGO_DEBUG: True

handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
  static_dir: static/

# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
  script: auto
# [END django_app]

-1

Geliştirme, test ve üretim için farklı ortamlarla benim çözümüm bu

import socket

[...]

DEV_PC = 'PC059'
host_name = socket.gethostname()

if host_name == DEV_PC:
   #do something
   pass
elif [...]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.