web-dev-qa-db-ja.com

Djangoでローカル設定と本番設定を管理する方法は?

ローカル開発と運用サーバーの設定を処理する推奨される方法は何ですか?それらの一部(定数など)は両方で変更/アクセスできますが、一部(静的ファイルへのパスなど)を変更する必要があるため、新しいコードがデプロイされるたびに上書きしないでください。

現在、settings.pyにすべての定数を追加しています。しかし、ローカルで定数を変更するたびに、それを運用サーバーにコピーし、運用固有の変更のためにファイルを編集する必要があります... :(

編集:この質問に対する標準的な回答はないようです。私は最も一般的な方法を受け入れました。

281
akv

settings.py ::

try:
    from local_settings import *
except ImportError as e:
    pass

local_settings.pyで必要なものをオーバーライドできます。その場合、バージョン管理から外れるはずです。しかし、あなたがコピーについて言及しているので、私はあなたがどれも使わないと推測しています;)

126
ohnoes

Djangoの2つのスクープ:Django 1.5のベストプラクティス 設定ファイルにバージョン管理を使用し、別のディレクトリにファイルを保存することをお勧めします。

project/
    app1/
    app2/
    project/
        __init__.py
        settings/
            __init__.py
            base.py
            local.py
            production.py
    manage.py

base.pyファイルには一般的な設定(MEDIA_ROOTやADMINなど)が含まれていますが、local.pyおよびproduction.pyにはサイト固有の設定があります。

基本ファイルsettings/base.py

INSTALLED_APPS = (
    # common apps...
)

ローカル開発設定ファイルsettings/local.py

from project.settings.base import *

DEBUG = True
INSTALLED_APPS += (
    'debug_toolbar', # and other apps for local development
)

ファイル制作設定ファイルsettings/production.py

from project.settings.base import *

DEBUG = False
INSTALLED_APPS += (
    # other apps for production site
)

次に、Djangoを実行するときに、--settingsオプションを追加します。

# Running Django for local development
$ ./manage.py runserver 0:8000 --settings=project.settings.local

# Running Django Shell on the production site
$ ./manage.py Shell --settings=project.settings.production

この本の著者は、Githubに サンプルプロジェクトレイアウトテンプレート も掲載しています。

281
Rudolf Olah

settings.pyの代わりに、次のレイアウトを使用します。

.
└── settings/
    ├── __init__.py  <= not versioned
    ├── common.py
    ├── dev.py
    └── prod.py

common.pyは、ほとんどの構成が存在する場所です。

prod.pyは共通からすべてをインポートし、オーバーライドする必要があるものをオーバーライドします。

from __future__ import absolute_import # optional, but I like it
from .common import *

# Production overrides
DEBUG = False
#...

同様に、dev.pycommon.pyからすべてをインポートし、オーバーライドする必要があるものをすべてオーバーライドします。

最後に、__init__.pyはロードする設定を決定する場所であり、シークレットを保存する場所でもあります(したがって、このファイルはバージョン管理されません)。

from __future__ import absolute_import
from .prod import *  # or .dev if you want dev

##### Django SECRETS
SECRET_KEY = '(3Gd6shenud@&57...'
DATABASES['default']['PASSWORD'] = 'f9kGH...'

##### OTHER SECRETS
AWS_SECRET_ACCESS_KEY = "h50fH..."

このソリューションについて私が気に入っているのは:

  1. 秘密を除くすべてがバージョン管理システムにあります
  2. ほとんどの構成は1つの場所にあります:common.py
  3. 製品固有のものはprod.pyに入り、開発者固有のものはdev.pyに入ります。それは簡単です。
  4. common.pyまたはprod.pydev.pyからのものをオーバーライドできます。また、__init__.pyのすべてのものをオーバーライドできます。
  5. それは簡単なpythonです。再インポートのハッキングはありません。
66
MiniQuark

Harper Shelbyが投稿した「if DEBUG」スタイルの設定を少し変更したバージョンを使用します。明らかに環境(win/linux/etc。)によっては、コードを少し調整する必要があるかもしれません。

以前は「if DEBUG」を使用していましたが、時々、DEUBGをFalseに設定してテストを行う必要があることがわかりました。環境が本番か開発かを区別したかったので、DEBUGレベルを自由に選択できました。

PRODUCTION_SERVERS = ['WEBSERVER1','WEBSERVER2',]
if os.environ['COMPUTERNAME'] in PRODUCTION_SERVERS:
    PRODUCTION = True
else:
    PRODUCTION = False

DEBUG = not PRODUCTION
TEMPLATE_DEBUG = DEBUG

# ...

if PRODUCTION:
    DATABASE_Host = '192.168.1.1'
else:
    DATABASE_Host = 'localhost'

私はまだこの設定方法は進行中の作業であると考えています。すべてのベースをカバーするDjango設定を処理する方法を1つも見たことがありませんでしたが、同時に設定の面倒な作業でもありませんでした(5x設定ファイルメソッドを使用しているわけではありません)。

20
T. Stone

私はsettings_local.pyとsettings_production.pyを使用します。いくつかのオプションを試した後、単純に2つの設定ファイルを簡単かつ迅速に使用できると、複雑なソリューションで時間を無駄にしやすいことがわかりました。

Djangoプロジェクトにmod_python/mod_wsgiを使用する場合、設定ファイルを指す必要があります。ローカルサーバーのapp/settings_local.pyと本番サーバーのapp/settings_production.pyを指定すると、作業が楽になります。適切な設定ファイルを編集してサーバーを再起動するだけです(Django開発サーバーは自動的に再起動します)。

14
Kai

Django-split-settings を使用して設定を管理します。

これはデフォルト設定のドロップイン代替品です。シンプルでありながら設定可能です。また、既存の設定のリファクタリングは必要ありません。

以下に小さな例を示します(ファイルexample/settings/__init__.py):

from split_settings.tools import optional, include
import os

if os.environ['Django_SETTINGS_MODULE'] == 'example.settings':
    include(
        'components/default.py',
        'components/database.py',
        # This file may be missing:
        optional('local_settings.py'),

        scope=globals()
    )

それでおしまい。

更新

Djangoの設定をDjango-split-sttingsで管理することについて ブログ投稿 を書きました。ご覧ください!

7
sobolevn

これらのソリューションのほとんどの問題は、ローカル設定が適用されていることですbefore一般的な設定、またはafterそれら。

そのため、次のようなものをオーバーライドすることは不可能です

  • 環境固有の設定はmemcachedプールのアドレスを定義し、メインの設定ファイルではこの値はキャッシュバックエンドの構成に使用されます
  • 環境固有の設定は、デフォルトのアプリケーション/ミドルウェアを追加または削除します

同時に。

1つのソリューションは、ConfigParserクラスで「ini」スタイルの構成ファイルを使用して実装できます。複数のファイル、遅延文字列補間、デフォルト値、その他多くの機能をサポートしています。多数のファイルがロードされると、さらに多くのファイルをロードでき、それらの値は前のファイルがあればそれをオーバーライドします。

マシンのアドレス、環境変数、および以前にロードされた構成ファイルの値に応じて、1つ以上の構成ファイルをロードします。次に、解析された値を使用して設定値を設定します。

私が成功裏に使用した戦略の1つは次のとおりです。

  • デフォルトのdefaults.iniファイルをロードします
  • マシン名を確認し、逆のFQDNに一致するすべてのファイルを、最短一致から最長一致までロードします(したがって、net.ininet.domain.ininet.domain.webserver01.iniをそれぞれロードしましたおそらく前の値をオーバーライドします)。このアカウントは開発者のマシンにも使用されるため、それぞれがローカル開発用に優先データベースドライバーなどを設定できます。
  • 「クラスター名」が宣言されているかどうかを確認します。その場合、データベースやキャッシュIPなどを定義できるcluster.cluster_name.iniをロードします

これで実現できることの例として、envごとに「サブドメイン」値を定義できます。これは、デフォルト設定(hostname: %(subdomain).whatever.net)で使用され、必要なホスト名とCookieのすべてを定義しますDjangoは動作する必要があります。

これは、DRYが取得できたように、ほとんどの(既存の)ファイルには3つまたは4つの設定しかありませんでした。これに加えて、顧客の構成を管理する必要があったため、顧客ごとに1つ以上の追加の構成ファイルセット(データベース名、ユーザーとパスワード、割り当てられたサブドメインなど)が存在しました。

これを必要に応じて低または高にスケーリングできます。環境ごとに構成するキーを構成ファイルに入れるだけで、新しい構成が必要になったら、以前の値をデフォルト構成に入れて上書きします必要に応じて。

このシステムは信頼性が実証されており、バージョン管理とうまく機能します。これは、2つのアプリケーションのクラスター(マシンごとにDjangoサイトの15以上の個別のインスタンス)を管理するために長い間使用されてきました。システム管理者の気分...

6
rewritten

TL; DR:トリックは、os.environmentsettings/base.pyをインポートする前にsettings/<purpose>.pyを変更することです。これにより、物事が大幅に簡素化されます。


これらの絡み合っているすべてのファイルについて考えるだけで、頭痛の種になります。 DEBUG設定が後で変更された場合に、既に設定されているものの結合、インポート(条件付き)、オーバーライド、パッチ適用。なんて悪夢だ!

何年もの間、私はすべての異なるソリューションを経験しました。それらはすべてやや動作しますが、管理するのはとても苦痛です。 WTF!面倒なことは本当に必要ですか? 1つのsettings.pyファイルから始めました。ここで、これらすべてを正しい順序で正しく組み合わせるために、ドキュメントが必要です!

私は最終的に以下の解決策で(私の)スイートスポットを打つことを願っています。

目標を要約しましょう(一般的なもの、私のもの)

  1. 秘密を秘密にしてください—リポジトリに保管しないでください!

  2. 環境設定でキーとシークレットを設定/読み取り、 12ファクタースタイル

  3. 適切なフォールバックデフォルトを設定します。ローカル開発では、デフォルト以外に何も必要ないのが理想的です。

  4. …しかし、デフォルトの生産を安全に保つようにしてください。本番環境で安全にデフォルト設定を調整することを覚えておくよりも、ローカルで設定のオーバーライドを見逃す方が適切です。

  5. 他の設定に影響を与える可能性のある方法でDEBUGのオン/オフを切り替える機能がある(たとえば、javascriptを圧縮して使用するかどうか)。

  6. ローカル/テスト/ステージング/プロダクションなどの目的設定の切り替えは、Django_SETTINGS_MODULEのみに基づいて行う必要があります。

  7. …ただし、DATABASE_URLなどの環境設定を使用して、さらにパラメーター化できます。

  8. …また、異なる目的の設定を使用して、ローカルで並べて実行することもできます。生産データベースにアクセスしたり、圧縮されたスタイルシートをテストしたりするための、ローカル開発マシン上の生産セットアップ。

  9. 特に本番環境などで、環境変数が明示的に設定されていない場合(少なくとも空の値が必要)、失敗します。 EMAIL_Host_PASSWORD

  10. Django-admin startproject の間にmanage.pyで設定されたデフォルトのDjango_SETTINGS_MODULEに応答します

  11. 条件が目的の環境タイプ(実稼働セットのログファイルとそのローテーションなど)である場合、条件を最小限に抑え、関連する目的の設定ファイルの設定をオーバーライドします。

しないでください

  1. DjangoにDjango_SETTINGS_MODULE設定を読み取らせないでください。
    うーん!これがいかにメタかを考えてください。ファイル(docker envなど)が必要な場合は、Djangoプロセスを開始する前にそれを環境に読み込みます。

  2. プロジェクト/アプリコードでDjango_SETTINGS_MODULEをオーバーライドしないでください。ホスト名またはプロセス名に基づきます。
    環境変数を設定するのが面倒(setup.py testなど)の場合は、プロジェクトコードを実行する直前にツールで実行してください。

  3. Djangoが設定を読み取る方法の魔法とパッチを避け、設定を前処理しますが、その後は干渉しません。

  4. 複雑なロジックベースのナンセンスはありません。構成は、オンザフライで計算されるのではなく、修正および具体化する必要があります。ここでは、フォールバックのデフォルトを提供するだけで十分なロジックです。
    本当にデバッグしたいのですが、なぜローカルに正しい設定がありますが、実稼働中のリモートサーバー、数百台のマシンのいずれかで、異なる計算が行われます。ああ!単体テスト?設定については?マジ?

解決

私の戦略は優れた Django-environ で構成され、iniスタイルファイルで使用され、ローカル開発用のos.environmentデフォルト、settings/<purpose>.pyを持つ最小限の短いimport settings/base.pyファイルを提供します。の後、os.environmentINIファイルから設定されました。これにより、一種の設定インジェクションが効果的に提供されます。

ここでのコツは、os.environmentをインポートする前にsettings/base.pyを変更することです。

完全な例を見るには、レポジトリを実行してください: https://github.com/wooyek/Django-settings-strategy

.
│   manage.py
├───data
└───website
    ├───settings
    │   │   __init__.py   <-- imports local for compatibility
    │   │   base.py       <-- almost all the settings, reads from proces environment 
    │   │   local.py      <-- a few modifications for local development
    │   │   production.py <-- ideally is empty and everything is in base 
    │   │   testing.py    <-- mimics production with a reasonable exeptions
    │   │   .env          <-- for local use, not kept in repo
    │   __init__.py
    │   urls.py
    │   wsgi.py

settings/.env

ローカル開発のデフォルト。ほとんどが必要な環境変数を設定するための秘密ファイル。ローカル開発で必要ない場合は、空の値に設定します。環境から欠落している場合、他のマシンで失敗するようにsettings/base.pyではなくここにデフォルトを提供します。

settings/local.py

ここで何が起こるかは、settings/.envから環境をロードし、settings/base.pyから共通設定をインポートすることです。その後、いくつかをオーバーライドして、ローカル開発を容易にすることができます。

import logging
import environ

logging.debug("Settings loading: %s" % __file__)

# This will read missing environment variables from a file
# We wan to do this before loading a base settings as they may depend on environment
environ.Env.read_env(DEBUG='True')

from .base import *

ALLOWED_HOSTS += [
    '127.0.0.1',
    'localhost',
    '.example.com',
    'vagrant',
    ]

# https://docs.djangoproject.com/en/1.6/topics/email/#console-backend
EMAIL_BACKEND = 'Django.core.mail.backends.console.EmailBackend'
# EMAIL_BACKEND = 'Django.core.mail.backends.dummy.EmailBackend'

LOGGING['handlers']['mail_admins']['email_backend'] = 'Django.core.mail.backends.dummy.EmailBackend'

# Sync task testing
# http://docs.celeryproject.org/en/2.5/configuration.html?highlight=celery_always_eager#celery-always-eager

CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True

settings/production.py

実稼働環境では、環境ファイルを期待するべきではありませんが、何かをテストする場合は環境ファイルを用意する方が簡単です。しかし、とにかく、インラインでデフォルトをほとんど提供しないため、settings/base.pyはそれに応じて応答できます。

environ.Env.read_env(Path(__file__) / "production.env", DEBUG='False', ASSETS_DEBUG='False')
from .base import *

ここで重要なのは、DEBUGおよびASSETS_DEBUGオーバーライドです。これらは、python os.environオーバーライドに適用されます。それらが環境およびファイルから欠落している場合のみです。

これらは本番環境のデフォルトであり、環境またはファイルに配置する必要はありませんが、必要に応じてオーバーライドできます。きちんとした!

settings/base.py

これらは主にVanilla Djangoの設定であり、いくつかの条件と環境からの多くの読み取りがあります。ほとんどすべてのものがここにあり、すべての目的の環境の一貫性と可能な限りの類似性を保ちます。

主な違いは次のとおりです(これらが自明であることを願っています)。

import environ

# https://github.com/joke2k/Django-environ
env = environ.Env()

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# Where BASE_DIR is a Django source root, ROOT_DIR is a whole project root
# It may differ BASE_DIR for eg. when your Django project code is in `src` folder
# This may help to separate python modules and *Django apps* from other stuff
# like documentation, fixtures, docker settings
ROOT_DIR = BASE_DIR

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', default=False)

INTERNAL_IPS = [
    '127.0.0.1',
]

ALLOWED_HOSTS = []

if 'ALLOWED_HOSTS' in os.environ:
    hosts = os.environ['ALLOWED_HOSTS'].split(" ")
    BASE_URL = "https://" + hosts[0]
    for Host in hosts:
        Host = Host.strip()
        if Host:
            ALLOWED_HOSTS.append(Host)

SECURE_SSL_REDIRECT = env.bool('SECURE_SSL_REDIRECT', default=False)

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

if "DATABASE_URL" in os.environ:  # pragma: no cover
    # Enable database config through environment
    DATABASES = {
        # Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
        'default': env.db(),
    }

    # Make sure we use have all settings we need
    # DATABASES['default']['ENGINE'] = 'Django.contrib.gis.db.backends.postgis'
    DATABASES['default']['TEST'] = {'NAME': os.environ.get("DATABASE_TEST_NAME", None)}
    DATABASES['default']['OPTIONS'] = {
        'options': '-c search_path=gis,public,pg_catalog',
        'sslmode': 'require',
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'Django.db.backends.sqlite3',
            # 'ENGINE': 'Django.contrib.gis.db.backends.spatialite',
            'NAME': os.path.join(ROOT_DIR, 'data', 'db.dev.sqlite3'),
            'TEST': {
                'NAME': os.path.join(ROOT_DIR, 'data', 'db.test.sqlite3'),
            }
        }
    }

STATIC_ROOT = os.path.join(ROOT_DIR, 'static')

# Django-assets
# http://Django-assets.readthedocs.org/en/latest/settings.html

ASSETS_LOAD_PATH = STATIC_ROOT
ASSETS_ROOT = os.path.join(ROOT_DIR, 'assets', "compressed")
ASSETS_DEBUG = env('ASSETS_DEBUG', default=DEBUG)  # Disable when testing compressed file in DEBUG mode
if ASSETS_DEBUG:
    ASSETS_URL = STATIC_URL
    ASSETS_MANIFEST = "json:{}".format(os.path.join(ASSETS_ROOT, "manifest.json"))
else:
    ASSETS_URL = STATIC_URL + "assets/compressed/"
    ASSETS_MANIFEST = "json:{}".format(os.path.join(STATIC_ROOT, 'assets', "compressed", "manifest.json"))
ASSETS_AUTO_BUILD = ASSETS_DEBUG
ASSETS_MODULES = ('website.assets',)

最後のビットは、ここでの力を示しています。 ASSETS_DEBUGには賢明なデフォルトがあり、settings/production.pyでオーバーライドでき、環境設定でオーバーライドすることもできます!わーい!

実際には、重要度の混合階層があります。

  1. settings/.py-目的に基づいてデフォルトを設定し、シークレットを保存しません
  2. settings/base.py-ほとんどは環境によって制御されます
  3. プロセス環境設定-12ファクターベイビー!
  4. settings/.env-簡単に起動できるローカルのデフォルト
5

私はLaravelにも取り組んでおり、そこでの実装が気に入っています。私はそれをまねて、T。Stoneが提案したソリューションと組み合わせようとしました(上記を参照)。

PRODUCTION_SERVERS = ['*.webfaction.com','*.whatever.com',]

def check_env():
    for item in PRODUCTION_SERVERS:
        match = re.match(r"(^." + item + "$)", socket.gethostname())
        if match:
            return True

if check_env():
    PRODUCTION = True
else:
    PRODUCTION = False

DEBUG = not PRODUCTION

たぶん、このような何かがあなたを助けるでしょう。

5
Robert Kuzma

Settings.pyはライブコードファイルであることを忘れないでください。実稼働環境でDEBUGを設定していないと仮定すると(これがベストプラクティスです)、次のようなことができます。

if DEBUG:
    STATIC_PATH = /path/to/dev/files
else:
    STATIC_PATH = /path/to/production/files

かなり基本的ですが、理論的には、DEBUGの値だけで、または使用したい他の変数またはコードチェックに基づいて、任意のレベルの複雑さまで上げることができます。

4
Harper Shelby

私のほとんどのプロジェクトでは、次のパターンを使用します。

  1. すべての環境に共通の設定を保存するsettings_base.pyを作成します
  2. 特定の要件を持つ新しい環境を使用する必要があるときはいつでも、settings_base.pyの内容を継承し、適切な設定変数(from settings_base import *)をオーバーライド/追加する新しい設定ファイル(たとえばsettings_local.py)を作成します

(カスタム設定ファイルでmanage.pyを実行するには、単に--settingsコマンドオプションを使用します:manage.py <command> --settings=settings_you_wish_to_use.py

4
dzida

上記のjpartogiのバリエーションを使用しますが、少し短くなっています。

import platform
from Django.core.management import execute_manager 

computername = platform.node()

try:
  settings = __import__(computername + '_settings')
except ImportError: 
  import sys
  sys.stderr.write("Error: Can't find the file '%r_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run Django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % (computername, __file__))
  sys.exit(1)

if __== "__main__":
  execute_manager(settings)

基本的に各コンピューター(開発または本番)に、動的にロードされる適切なhostname_settings.pyファイルがあります。

3
stratosgear

Django Classy Settingsもあります。私は個人的にそれの大ファンです。 Django IRCで最も活発な人の一人によって構築されています。環境変数を使用して設定します。

http://Django-classy-settings.readthedocs.io/en/latest/

3
SudoKid

この問題に対する私の解決策は、ここですでに述べたいくつかの解決策の混合です。

  • local_settings.pyという名前のファイルを保持します。このファイルには、devのUSING_LOCAL = TrueコンテンツとprodのUSING_LOCAL = Falseコンテンツがあります
  • settings.pyでそのファイルをインポートしてUSING_LOCAL設定を取得します

次に、環境に依存するすべての設定をその設定に基づきます。

DEBUG = USING_LOCAL
if USING_LOCAL:
    # dev database settings
else:
    # prod database settings

設定を複数のファイルに分散させるよりも簡単に単一のファイルに構造化を維持できるため、これを維持する必要がある2つの個別のsettings.pyファイルを用意することをお勧めします。このように、設定を更新するときは、両方の環境でそれを行うことを忘れないでください。

もちろん、すべての方法には欠点があり、これも例外ではありません。ここでの問題は、変更を本番環境にプッシュするたびにlocal_settings.pyファイルを上書きできないことです。つまり、すべてのファイルを盲目的にコピーすることはできませんが、それは一緒に生きることができます。

3
Miguel Ventura

異なる環境で異なるsettings構成を使用するには、異なる設定ファイルを作成します。また、デプロイメントスクリプトで、 --settings=<my-settings.py> パラメーターを使用してサーバーを起動します。このパラメーターを使用して、異なる環境で異なるsettingsを使用できます。

このアプローチを使用する利点

  1. 設定は各環境に基づいてモジュール化されます

  2. master_settings.pyに基本構成を含むenvironmnet_configuration.pyをインポートし、その環境で変更する値をオーバーライドできます。

  3. 巨大なチームがある場合、各開発者は独自のlocal_settings.pyを持っている可能性があり、サーバー構成を変更するリスクなしにコードリポジトリに追加できます。 gitを使用する場合は、これらのローカル設定を.gitnoreに追加できます。MercurialVersion Control(またはその他)に使用する場合は、.hginoreを追加できます。そうすれば、ローカル設定は、実際のコードベースの一部でさえありません。

2

1-アプリ内に新しいフォルダーを作成し、設定に名前を付けます。

2-新しいinit。pyファイルを作成し、その中に書き込みます

    from .base import *

    try:

        from .local import *

    except:

        pass

     try:

         from .production import *

     except:

         pass

3-設定フォルダー名local.pyおよびproduction.pyおよびbase.pyに3つの新しいファイルを作成します

4-base.py内で、以前のsettings.pフォルダーのすべてのコンテンツをコピーし、old_settings.pyと言う別の名前に変更します

5-base.pyで、BASE_DIRパスを設定の新しいパスを指すように変更します

古いパス-> BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))

新しいパス-> BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(file)))

このようにして、プロジェクトディレクトリを構造化して、本番環境とローカル開発の間で管理できるようになりました。

1
Jack Ryan

Wiilを使用して別のファイルを維持する代わりに:gitまたは他のVCSを使用してコードをローカルからサーバーにプッシュする場合、設定ファイルを.gitignoreに追加します。

これにより、問題なく両方の場所で異なるコンテンツを使用できます。 SOサーバーでは、settings.pyの独立したバージョンを構成でき、ローカルで行われた変更はサーバーに反映され、その逆も同様です。

さらに、githubからsettings.pyファイルも削除されます。これは、多くの初心者が行っている大きな欠点です。

1
sprksh

Manage.pyで区別し、local_settings.pyとprod_settings.pyの2つの設定ファイルを作成しました。

Manage.pyで、サーバーがローカルサーバーか運用サーバーかを確認します。ローカルサーバーの場合はlocal_settings.pyをロードし、運用サーバーの場合はprod_settings.pyをロードします。基本的には次のようになります。

#!/usr/bin/env python
import sys
import socket
from Django.core.management import execute_manager 

ipaddress = socket.gethostbyname( socket.gethostname() )
if ipaddress == '127.0.0.1':
    try:
        import local_settings # Assumed to be in the same directory.
        settings = local_settings
    except ImportError:
        import sys
        sys.stderr.write("Error: Can't find the file 'local_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run Django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
        sys.exit(1)
else:
    try:
        import prod_settings # Assumed to be in the same directory.
        settings = prod_settings    
    except ImportError:
        import sys
        sys.stderr.write("Error: Can't find the file 'prod_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run Django-admin.py, passing it your settings module.\n(If the file prod_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
        sys.exit(1)

if __== "__main__":
    execute_manager(settings)

設定ファイル内で大量のifを行うよりも、設定ファイルを2つの別々のファイルに分ける方が簡単であることがわかりました。

1
Joshua Partogi

次のように設定を分割しました

settings/
     |
     |- base.py
     |- dev.py
     |- prod.py  

3つの環境があります

  • 開発者
  • ステージング
  • 製造

ステージングとプロダクションには、可能な限り最大限の類似環境が必要です。そのため、両方に対してprod.pyを保持しました。

しかし、実行中のサーバーが運用サーバーであることを特定しなければならない場合がありました。 @T。ストーンの答えは、次のように小切手を書くのに役立ちました。

from socket import gethostname, gethostbyname  
PROD_HOSTS = ["webserver1", "webserver2"]

DEBUG = False
ALLOWED_HOSTS = [gethostname(), gethostbyname(gethostname()),]


if any(Host in PROD_HOSTS for Host in ALLOWED_HOSTS):
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True  
1
Kishor Pawar

@Tが最善の解決策を提案していると思います。ストーン。でも、なぜDjangoでDEBUGフラグを使用しないのかわかりません。私は私のウェブサイトのために以下のコードを書きます:

if DEBUG:
    from .local_settings import *

常に単純なソリューションは複雑なソリューションよりも優れています。

0
seyedrezafar

Settings.pyの複数のバージョンを作成することは、 12ファクターアプリ手法 のアンチパターンです。代わりに python-decouple または Django-environ を使用してください。

0