คุณกำหนดค่า Django สำหรับการพัฒนาและปรับใช้อย่างง่ายได้อย่างไร


112

ฉันมักจะใช้SQLiteเมื่อทำการ พัฒนาDjangoแต่บนเซิร์ฟเวอร์ที่ใช้งานจริงมักต้องการสิ่งที่มีประสิทธิภาพมากกว่า (เช่นMySQL / PostgreSQL ) มีการเปลี่ยนแปลงอื่น ๆ ที่ต้องทำกับการตั้งค่า Django เช่นกัน: ตำแหน่งการบันทึก / ความเข้มที่แตกต่างกันเส้นทางสื่อ ฯลฯ

คุณจะจัดการการเปลี่ยนแปลงทั้งหมดนี้อย่างไรเพื่อให้การปรับใช้เป็นกระบวนการอัตโนมัติที่เรียบง่าย


ฉันไม่ได้ทำอะไรแฟนซีเหมือนคนอื่น ๆ :) ฉันแค่ใช้ประโยชน์จาก ORM ที่ django ให้มา
Andrew Sledge

1
คำถามคือวิธีการเปลี่ยนการตั้งค่าโดยอัตโนมัติเพื่อสลับระหว่างสภาพแวดล้อม :-)
Guruprasad


คุณสามารถดูแพ็คเกจนี้: django-split-settings
sobolevn

คำตอบ:


86

อัปเดต: การกำหนดค่า djangoได้รับการเผยแพร่ซึ่งน่าจะเป็นตัวเลือกที่ดีกว่าสำหรับคนส่วนใหญ่มากกว่าการทำด้วยตนเอง

หากคุณต้องการทำสิ่งต่างๆด้วยตนเองคำตอบก่อนหน้าของฉันยังคงใช้ได้:

ฉันมีไฟล์การตั้งค่าหลายไฟล์

  • settings_local.py - การกำหนดค่าโฮสต์เฉพาะเช่นชื่อฐานข้อมูลเส้นทางไฟล์ ฯลฯ
  • settings_development.py- DEBUG = Trueการกำหนดค่าใช้ในการพัฒนาเช่น
  • settings_production.py- SERVER_EMAILการกำหนดค่าใช้สำหรับการผลิตเช่น

ฉันรวมสิ่งเหล่านี้เข้าด้วยกันกับsettings.pyไฟล์ที่นำเข้าก่อนsettings_local.pyจากนั้นหนึ่งในอีกสองไฟล์ มันตัดสินใจที่จะโหลดโดยตั้งค่าทั้งสองภายในsettings_local.py- และ DEVELOPMENT_HOSTS เรียกเพื่อค้นหาชื่อโฮสต์ของเครื่องที่กำลังทำงานอยู่จากนั้นค้นหาชื่อโฮสต์นั้นในรายการและโหลดไฟล์การตั้งค่าที่สองขึ้นอยู่กับรายการที่พบชื่อโฮสต์ในPRODUCTION_HOSTSsettings.pyplatform.node()

ด้วยวิธีนี้สิ่งเดียวที่คุณต้องกังวลคือการทำให้settings_local.pyไฟล์เป็นปัจจุบันด้วยการกำหนดค่าเฉพาะโฮสต์และทุกอย่างจะได้รับการจัดการโดยอัตโนมัติ

ตรวจสอบตัวอย่างที่นี่


2
จะเกิดอะไรขึ้นถ้าการจัดเตรียม (การพัฒนา) และการผลิตอยู่ในเครื่องเดียวกัน? platform.node () ส่งคืนค่าเดียวกันแล้ว
gwaramadze

2
ลิงค์ตัวอย่างล่ม
Jickson

ความคิดที่ดีในการพิจารณาการตั้งถิ่นฐานตามรายชื่อโฮสต์! nitpick ของฉันคือระบบการตั้งชื่อ (settings_local.py จะถูกนำเข้าก่อนเสมอดังนั้นการตั้งค่าใด ๆ ที่ไม่ถูกลบล้างจะยังคงทำงานอยู่ในการผลิตทำให้คำต่อท้าย_localค่อนข้างสับสน) และความจริงที่ว่าคุณไม่ได้ใช้โมดูล (การตั้งค่า /base.py, settings / local.py, settings / 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 ต่างๆที่ทำงานบนโฮสต์เดียวกัน สิ่งนี้จะเกิดขึ้นตัวอย่างเช่นหากคุณมีอินสแตนซ์ที่ต่างกันที่ทำงานสำหรับโดเมนย่อยที่แตกต่างกันบนโฮสต์เดียวกัน
Erik

24

ในตอนท้ายของ settings.py ฉันมีสิ่งต่อไปนี้:

try:
    from settings_local import *
except ImportError:
    pass

วิธีนี้หากฉันต้องการลบล้างการตั้งค่าเริ่มต้นฉันต้องใส่ settings_local.py ไว้ข้างๆ settings.py


4
นี้เป็นอันตรายเล็กน้อยเพราะถ้าพิมพ์ผิดในsettings_localผลการค้นหาในImportErrorนี้exceptจะกลืนมันเงียบ
Chris Martin

คุณสามารถตรวจสอบข้อความNo module named...เทียบกับcannot import name...แต่มันเปราะ หรือใส่การนำเข้าของคุณใน settings_local.py ในการลองบล็อกและเพิ่มข้อยกเว้นที่เฉพาะเจาะจงมากขึ้น: MisconfiguredSettingsหรือบางสิ่งบางอย่างเพื่อให้เกิดผลดังกล่าว
DylanYoung

11

ฉันมีสองไฟล์ settings_base.pyซึ่งมีการตั้งค่าทั่วไป / ค่าเริ่มต้นและตรวจสอบการควบคุมแหล่งที่มา การปรับใช้แต่ละครั้งมีการแยกกันsettings.pyซึ่งดำเนินfrom settings_base import *การในตอนเริ่มต้นจากนั้นจะลบล้างตามความจำเป็น


1
ฉันก็ใช้ตัวนี้เหมือนกัน ดีกว่าการผกผัน ("from settings_local import *" ของ dmishe ที่ส่วนท้ายของ settings.py) เนื่องจากช่วยให้การตั้งค่าภายในสามารถเข้าถึงและแก้ไขการตั้งค่าส่วนกลางได้หากจำเป็น
Carl Meyer

3
หากsettings_local.pyทำเช่นนี้from settings import *จะสามารถแทนที่ค่าในsettings.py. ( settings_local.pyต้องนำเข้าไฟล์ที่ท้ายsettings.py)
Seth

ที่สามารถทำได้ ดูที่stackoverflow.com/a/7047633/3124256ด้านบน @ เซ ธ นั่นคือสูตรการนำเข้าแบบวงกลม
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) เราใช้โปรแกรมติดตั้งอย่างกว้างขวางเมื่อทำให้การปรับใช้งานเป็นไปโดยอัตโนมัติภายใน (สามารถรันในโหมดไม่ต้องใส่ข้อมูลได้)


1
อีกทางเลือกหนึ่งฉันอยากจะแนะนำDjango Turnkey Linux ที่ใช้ Ubuntu * NIX stack ที่ติดตั้ง django ไว้ล่วงหน้า
jochem

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 เช่นนี้ (แทนที่ด้วย directoy ที่รหัส dev ของคุณอยู่):

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

จากนั้นทุกครั้งที่ย้ายไฟล์ settings.py DEBUG จะเป็น False และเป็นสภาพแวดล้อมการใช้งานจริงของคุณ

ทุกครั้งที่คุณต้องการการตั้งค่าที่แตกต่างจากการตั้งค่าในสภาพแวดล้อม dev ของคุณเพียงแค่ใช้:

if(DEBUG):
    #Debug setting
else:
    #Release setting

0

ฉันคิดว่ามันขึ้นอยู่กับขนาดของไซต์ว่าคุณจำเป็นต้องก้าวขึ้นจากการใช้ SQLite หรือไม่ฉันใช้ SQLite ในไซต์สดขนาดเล็กหลายแห่งได้สำเร็จและทำงานได้ดี


0

ฉันใช้สภาพแวดล้อม:

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

ฉันเชื่อว่านี่เป็นแนวทางที่ดีกว่ามากเพราะในที่สุดคุณต้องมีการตั้งค่าพิเศษสำหรับสภาพแวดล้อมการทดสอบของคุณและคุณสามารถเพิ่มลงในเงื่อนไขนี้ได้อย่างง่ายดาย


0

นี่เป็นโพสต์เก่า แต่ฉันคิดว่าถ้าฉันเพิ่มสิ่งนี้มีประโยชน์ libraryมันจะทำให้สิ่งต่างๆง่ายขึ้น

ใช้django-configuration

Quickstart

pip install django-configurations

จากนั้นซับคลาสการกำหนดค่าที่รวมไว้คลาสคอนฟิกูเรชันใน 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ตัวเลือกบรรทัดคำสั่งเริ่มต้นของ Django เช่น:

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

ในการเปิดใช้งาน Django เพื่อใช้การกำหนดค่าของคุณตอนนี้คุณต้องแก้ไขสคริปต์Manage.pyหรือwsgi.pyของคุณเพื่อใช้เวอร์ชันเริ่มต้นของฟังก์ชันเริ่มต้นที่เหมาะสมของ django-configurations เช่นManage.pyทั่วไปที่ใช้ django-configuration จะมีลักษณะดังนี้:

#!/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_lineconfigurations.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 เหล่านั้นเพียงแค่ใช้หาง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.