Bagaimana Anda mengkonfigurasi Django untuk pengembangan dan penerapan sederhana?

112

Saya cenderung menggunakan SQLite ketika melakukan pengembangan Django , tetapi pada server langsung sesuatu yang lebih kuat sering dibutuhkan ( MySQL / PostgreSQL , misalnya). Selalu, ada perubahan lain yang harus dilakukan pada pengaturan Django juga: lokasi / intensitas pencatatan berbeda, jalur media, dll.

Bagaimana Anda mengelola semua perubahan ini untuk membuat penerapan menjadi proses otomatis yang sederhana?

Peter Mortensen
sumber
Saya tidak melakukan sesuatu yang mewah seperti orang lain :). Saya hanya memanfaatkan ORM yang disuplai Django.
Andrew Sledge
1
Pertanyaannya adalah tentang bagaimana mengotomatiskan perubahan pengaturan untuk beralih antar lingkungan :-)
Guruprasad
Anda dapat melihat paket ini: django-split-settings
sobolevn

Jawaban:

86

Pembaruan: django-configurations telah dirilis yang mungkin merupakan pilihan yang lebih baik bagi kebanyakan orang daripada melakukannya secara manual.

Jika Anda lebih suka melakukan sesuatu secara manual, jawaban saya sebelumnya masih berlaku:

Saya memiliki beberapa file pengaturan.

  • settings_local.py - konfigurasi khusus host, seperti nama database, jalur file, dll.
  • settings_development.py- konfigurasi yang digunakan untuk pengembangan, misalnya DEBUG = True.
  • settings_production.py- konfigurasi yang digunakan untuk produksi, misalnya SERVER_EMAIL.

Saya mengikat ini semua bersama dengan settings.pyfile yang pertama diimpor settings_local.py, dan kemudian salah satu dari dua lainnya. Ini memutuskan mana yang akan dimuat dengan dua pengaturan di dalam settings_local.py- DEVELOPMENT_HOSTSdan PRODUCTION_HOSTS. settings.pypanggilan platform.node()untuk menemukan nama host dari mesin yang menjalankannya, dan kemudian mencari nama host tersebut dalam daftar, dan memuat file pengaturan kedua tergantung pada daftar di mana ia menemukan nama host tersebut.

Dengan begitu, satu-satunya hal yang benar-benar perlu Anda khawatirkan adalah menjaga agar settings_local.pyfile tetap mutakhir dengan konfigurasi khusus host, dan yang lainnya ditangani secara otomatis.

Lihat contohnya di sini .

Jim
sumber
2
bagaimana jika pementasan (pengembangan) dan produksi berada di mesin yang sama? platform.node () mengembalikan yang sama.
gwaramadze
2
Contoh link sedang down.
Jickson
Ide bagus untuk menentukan settiings berdasarkan daftar host! Satu nitpick saya adalah nomenklatur (settings_local.py selalu diimpor terlebih dahulu sehingga pengaturan apa pun yang tidak diganti, sebenarnya masih aktif dalam produksi, membuat sufiks _localagak membingungkan) dan fakta bahwa Anda tidak menggunakan modul (pengaturan /base.py, settings / local.py, settings / production.py). Akan bijaksana juga untuk menyimpan ini dalam repositori terpisah ... lebih baik lagi, layanan aman yang menyajikan informasi ini dari sumber kanonik (mungkin berlebihan untuk sebagian besar) ... sehingga host baru tidak memerlukan rilis baru.
DylanYoung
Lebih baik lagi, jika Anda menggunakan perangkat lunak manajemen mesin, daripada memeriksa daftar host di .pyfile, dan dengan demikian memberikan setiap host akses ke informasi tentang konfigurasi setiap host lain, Anda dapat membuat template manage.py untuk menggunakan pengaturan yang sesuai file dalam konfigurasi penerapan Anda.
DylanYoung
26

Secara pribadi, saya menggunakan satu settings.py untuk proyek tersebut, saya baru saja mencari nama hostnya (mesin pengembangan saya memiliki nama host yang dimulai dengan "gabriel" jadi saya hanya punya ini:

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

lalu di bagian lain saya memiliki hal-hal seperti:

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

dan seterusnya. Sedikit kurang dapat dibaca, tetapi berfungsi dengan baik dan menghemat keharusan untuk menyulap beberapa file pengaturan.

Gabriel Ross
sumber
Saya menyukai gagasan ini, tetapi tidak mengizinkan saya untuk membedakan antara contoh Django berbeda yang berjalan pada host yang sama. Ini akan terjadi, misalnya, jika Anda memiliki instance berbeda yang menjalankan subdomain berbeda di host yang sama.
Erik
24

Di akhir settings.py saya memiliki yang berikut ini:

try:
    from settings_local import *
except ImportError:
    pass

Dengan cara ini jika saya ingin mengganti pengaturan default saya hanya perlu meletakkan settings_local.py tepat di sebelah settings.py.

Dmitry Shevchenko
sumber
4
Ini sedikit berbahaya karena jika salah ketik settings_localmenghasilkan ImportError, ini exceptakan menelannya secara diam-diam.
Chris Martin
Anda dapat memeriksa pesannya No module named...vs. cannot import name..., tetapi rapuh. Atau, letakkan impor Anda di settings_local.py di blok percobaan dan buat pengecualian yang lebih spesifik: MisconfiguredSettingsatau sesuatu untuk efek itu.
DylanYoung
11

Saya memiliki dua file. settings_base.pyyang berisi pengaturan umum / default, dan yang diperiksa ke kontrol sumber. Setiap penerapan memiliki yang terpisah settings.py, yang dijalankan from settings_base import *di awal dan kemudian diganti sesuai kebutuhan.

John Millikin
sumber
1
Saya menggunakan ini juga. Ini lebih unggul dari invers (dmishe's "from settings_local import *" di akhir settings.py) karena memungkinkan pengaturan lokal untuk mengakses dan memodifikasi yang global jika diperlukan.
Carl Meyer
3
Jika settings_local.pymelakukan ini from settings import *, ini dapat mengganti nilai dalam settings.py. ( settings_local.pyfile harus diimpor di akhir settings.py).
Seth
Itu bisa dilakukan. Lihat stackoverflow.com/a/7047633/3124256 di atas. @Seth Itu resep untuk impor melingkar.
DylanYoung
7

Cara paling sederhana yang saya temukan adalah:

1) gunakan default settings.py untuk pengembangan lokal dan 2) buat produksi-settings.py dimulai dengan:

import os
from settings import *

Dan kemudian timpa saja pengaturan yang berbeda dalam produksi:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}
Andre Bossard
sumber
Bagaimana django tahu untuk memuat pengaturan-produksi?
AlxVallejo
2

Sedikit terkait, untuk masalah menyebarkan Django itu sendiri dengan banyak basis data, Anda mungkin ingin melihat Djangostack . Anda dapat mengunduh penginstal gratis yang memungkinkan Anda menginstal Apache, Python, Django, dll. Sebagai bagian dari proses instalasi, kami mengizinkan Anda untuk memilih database mana yang ingin Anda gunakan (MySQL, SQLite, PostgreSQL). Kami menggunakan installer secara ekstensif saat mengotomatiskan penerapan secara internal (mereka dapat dijalankan dalam mode tanpa pengawasan).

Josue
sumber
1
Alternatifnya saya ingin merekomendasikan Django Turnkey Linux berdasarkan pada tumpukan Ubuntu * NIX dengan django yang telah diinstal sebelumnya.
jochem
1

Saya memiliki file settings.py saya di direktori eksternal. Dengan begitu, itu tidak diperiksa ke dalam kontrol sumber, atau ditimpa oleh penerapan. Saya meletakkan ini di file settings.py di bawah proyek Django saya, bersama dengan pengaturan default:

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

Catatan: Ini sangat berbahaya jika Anda tidak bisa mempercayai local_settings.py.

Chase Seibert
sumber
1

Selain beberapa file pengaturan yang disebutkan oleh Jim, saya juga cenderung menempatkan dua pengaturan ke dalam file settings.py saya di bagian atas BASE_DIRdan BASE_URLmengatur ke jalur kode dan URL ke dasar situs, semua pengaturan lainnya dimodifikasi untuk menambahkan diri mereka sendiri ke ini.

BASE_DIR = "/home/sean/myapp/" misalnya MEDIA_ROOT = "%smedia/" % BASEDIR

Jadi saat memindahkan proyek saya hanya perlu mengedit pengaturan ini dan tidak mencari seluruh file.

Saya juga akan merekomendasikan melihat fabric dan Capistrano (alat Ruby, tetapi dapat digunakan untuk menyebarkan aplikasi Django) yang memfasilitasi otomatisasi penyebaran jarak jauh.

Sean O Donnell
sumber
Ansible adalah python dan menawarkan fasilitas penyediaan yang jauh lebih kuat daripada Fabric. Mereka juga berpasangan dengan baik.
DylanYoung
1

Nah, saya menggunakan konfigurasi ini:

Di akhir settings.py:

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

Dan di 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
sumber
1

Begitu banyak jawaban yang rumit!

Setiap file settings.py dilengkapi dengan:

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

Saya menggunakan direktori itu untuk mengatur variabel DEBUG seperti ini (ganti dengan directoy di mana kode dev Anda):

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

Kemudian, setiap kali file settings.py dipindahkan, DEBUG akan menjadi False dan itu adalah lingkungan produksi Anda.

Setiap kali Anda membutuhkan pengaturan yang berbeda dari yang ada di lingkungan dev Anda, cukup gunakan:

if(DEBUG):
    #Debug setting
else:
    #Release setting
JM Desrosiers
sumber
0

Saya pikir itu tergantung pada ukuran situs, apakah Anda perlu meningkatkan dari menggunakan SQLite, saya telah berhasil menggunakan SQLite di beberapa situs langsung yang lebih kecil dan itu berjalan dengan baik.

Ycros
sumber
0

Saya menggunakan lingkungan:

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

Saya yakin ini adalah pendekatan yang jauh lebih baik, karena pada akhirnya Anda memerlukan pengaturan khusus untuk lingkungan pengujian Anda, dan Anda dapat dengan mudah menambahkannya ke kondisi ini.

slashmili.dll
sumber
0

Ini adalah posting yang lebih lama tetapi saya pikir jika saya menambahkan ini berguna libraryitu akan menyederhanakan banyak hal.

Gunakan django-configuration

Mulai cepat

pip install django-configurations

Kemudian buat subkelas dari kelas configurations.Configuration yang disertakan dalam proyek Anda settings.py atau modul lain yang Anda gunakan untuk menyimpan konstanta pengaturan, misalnya:

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

Setel DJANGO_CONFIGURATIONvariabel lingkungan ke nama kelas yang baru saja Anda buat, misalnya di ~/.bashrc:

export DJANGO_CONFIGURATION=Dev

dan DJANGO_SETTINGS_MODULEvariabel lingkungan ke jalur impor modul seperti biasa, misalnya di bash:

export DJANGO_SETTINGS_MODULE=mysite.settings

Alternatifnya sediakan --configurationopsi saat menggunakan perintah manajemen Django sepanjang --settingsbaris opsi baris perintah bawaan Django , misalnya:

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

Untuk mengaktifkan Django untuk menggunakan konfigurasi Anda sekarang harus mengubah Anda manage.py atau wsgi.py script untuk menggunakan versi Django-konfigurasi fungsi pemula yang tepat, misalnya khas manage.py menggunakan Django-konfigurasi akan terlihat seperti ini:

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

Perhatikan pada baris 10 kami tidak menggunakan alat umum django.core.management.execute_from_command_linemelainkan configurations.management.execute_from_command_line.

Hal yang sama berlaku untuk file wsgi.py Anda , misalnya:

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

Di sini kami tidak menggunakan django.core.wsgi.get_wsgi_applicationfungsi default melainkan configurations.wsgi.get_wsgi_application.

Itu dia! Anda sekarang dapat menggunakan proyek Anda dengan manage.py dan server berkemampuan WSGI favorit Anda.

Little Phild
sumber
-2

Bahkan Anda mungkin harus mempertimbangkan untuk memiliki konfigurasi yang sama (atau hampir sama) untuk lingkungan pengembangan dan produksi Anda. Jika tidak, situasi seperti "Hai, ini berfungsi di mesin saya" akan terjadi dari waktu ke waktu.

Jadi untuk mengotomatiskan penerapan Anda dan menghilangkan masalah WOMM tersebut, cukup gunakan Docker .

Dmitrii Mikhailov
sumber