我一直在开发一个基本的应用程序。现在处于部署阶段,我很清楚我需要本地设置和生产设置。
了解以下内容会很棒:
答案 0 :(得分:87)
DJANGO_SETTINGS_MODULE
environment variable控制Django将加载哪个设置文件。
因此,您可以为各自的环境创建单独的配置文件(请注意,它们当然可以来自单独的“共享设置”文件中的import *
),并使用DJANGO_SETTINGS_MODULE
来控制使用哪个环境
以下是:
如Django文档中所述:
DJANGO_SETTINGS_MODULE的值应采用Python路径语法,例如: mysite.settings。请注意,设置模块应位于Python导入搜索路径上。
因此,我们假设您在源存储库中创建了myapp/production_settings.py
和myapp/test_settings.py
。
在这种情况下,您分别设置DJANGO_SETTINGS_MODULE=myapp.production_settings
使用前者,DJANGO_SETTINGS_MODULE=myapp.test_settings
使用后者。
从现在开始,问题归结为设置DJANGO_SETTINGS_MODULE
环境变量。
DJANGO_SETTINGS_MODULE
然后,您可以使用引导脚本或进程管理器加载正确的设置(通过设置环境),或者在启动Django之前从shell运行它:export DJANGO_SETTINGS_MODULE=myapp.production_settings
。
请注意,您可以随时从shell运行此导出 - 它不需要存在于您的.bashrc
或其他任何内容中。
DJANGO_SETTINGS_MODULE
如果您不喜欢编写设置环境的引导脚本(并且有很好的理由感受到这种方式!),我建议使用进程管理器:
environment
configuration key将环境变量传递给托管进程。.env
) file中定义环境变量。最后,请注意您可以利用PYTHONPATH
变量将设置存储在完全不同的位置(例如,在生产服务器上,将它们存储在/etc/
中)。这允许将配置与应用程序文件分开。您可能有也可能不想要,这取决于您的应用程序的结构。
答案 1 :(得分:33)
默认使用生产设置,但在与settings_dev.py
文件相同的文件夹中创建名为settings.py
的文件。在那里添加覆盖,例如DEBUG=True
。
在将用于开发的计算机上,将其添加到~/.bashrc
文件中:
export DJANGO_DEVELOPMENT=true
在settings.py
文件的底部,添加以下内容。
# Override production variables if DJANGO_DEVELOPMENT env variable is set
if os.environ.get('DJANGO_DEVELOPMENT') is not None:
from settings_dev import *
(请注意,在Python中通常应避免导入*
,但这是一种独特的情况)
默认情况下,生产服务器不会覆盖任何内容。完成!
与其他答案相比,这个答案更简单,因为它不需要更新PYTHONPATH
,或设置DJANGO_SETTINGS_MODULE
,它只允许您一次处理一个django项目。
答案 2 :(得分:30)
我通常每个环境都有一个设置文件和一个共享设置文件:
/myproject/
settings.production.py
settings.development.py
shared_settings.py
我的每个环境文件都有:
try:
from shared_settings import *
except ImportError:
pass
这允许我在必要时覆盖共享设置(通过添加该节下面的修改)。
然后我通过将其链接到settings.py:
来选择要使用的设置文件ln -s settings.development.py settings.py
答案 3 :(得分:9)
创建多个settings*.py
文件,推断需要根据环境更改的变量。然后在主settings.py
文件的末尾:
try:
from settings_dev import *
except ImportError:
pass
您为每个阶段保留单独的settings_*
个文件。
在settings_dev.py
文件的顶部,添加以下内容:
import sys
globals().update(vars(sys.modules['settings']))
导入需要修改的变量。
此wiki entry有关于如何拆分设置的更多想法。
答案 4 :(得分:5)
这是我通过6个简单步骤完成的操作:
在项目目录中创建一个文件夹,并将其命名为settings
。
项目结构:
myproject/
myapp1/
myapp2/
myproject/
settings/
在settings
目录内创建四个python文件,分别为init.py
,base.py
,dev.py
和prod.py
设置文件:
setting/
init.py
base.py
prod.py
dev.py
打开init.py
并填写以下内容:
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 *
打开base.py
并用所有常用设置(将同时用于生产和开发)进行填充。
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/'
打开dev.py
并包含特定于开发的内容,例如:
dev.py:
DEBUG = True
ALLOWED_HOSTS = ['localhost']
...
打开prod.py
并包含特定于生产的内容,例如:
prod.py:
DEBUG = False
ALLOWED_HOSTS = ['www.example.com']
LOGGING = [...]
...
答案 5 :(得分:4)
我使用了真棒django-configurations,所有设置都存储在我的import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JList;
public class GuiApp1 {
public static void main(String args[]) {
String title = (args.length == 0 ? "CheckBox Sample" : args[0]);
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new GridLayout(0, 1));
Border border = BorderFactory.createTitledBorder("Pizza Toppings");
panel.setBorder(border);
JLabel label1 = new JLabel("Enter name below:");
panel.add(label1);
JTextField field = new JTextField(20);
panel.add(field);
JCheckBox check = new JCheckBox("Car0");
panel.add(check);
check = new JCheckBox("Car1");
panel.add(check);
check = new JCheckBox("Car2");
panel.add(check);
check = new JCheckBox("Car3");
panel.add(check);
check = new JCheckBox("Car4");
panel.add(check);
JButton button = new JButton("Submit");
final JPanel listPanel = new JPanel();
listPanel.setVisible(false);
JLabel listLbl = new JLabel("Vegetables:");
listPanel.add(listLbl);
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
listPanel.setVisible(!listPanel.isVisible());
panel.setVisible(!panel.isVisible());
}
});
Container contentPane = frame.getContentPane();
contentPane.add(panel, BorderLayout.CENTER);
contentPane.add(button, BorderLayout.SOUTH);
frame.setSize(300, 300);
frame.setResizable(true);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
中:
settings.py
要配置Django项目,我只需遵循docs。
答案 6 :(得分:3)
以下是我们使用的方法:
settings
模块,用于将设置拆分为多个文件以便于阅读; .env.json
文件,用于存储我们希望从我们的git存储库中排除的凭据和参数,或者是特定于环境的文件; env.py
文件,以阅读.env.json
文件...
.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
...
.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",
}
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()
<!-- 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',
}
}
.env.json
,例如开发,停滞和生产; 我希望这会有所帮助,如果您对此解决方案有任何警告,请告诉我。
答案 7 :(得分:2)
建立cs01的回答:
如果您遇到环境变量问题,请将其值设置为字符串(例如,我执行DJANGO_DEVELOPMENT="true"
)。
我还更改了cs01的文件工作流程,如下所示:
#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
这样,Django在运行相应的设置文件之前不必读取整个设置文件。如果您的生产文件只需要生产服务器上的东西,这个解决方案就派上用场了。
注意:在Python 3中,导入的文件需要附加.
(例如from .settings_dev import *
)
答案 8 :(得分:2)
我使用了文件结构:
project/
...
settings/
settings/common.py
settings/local.py
settings/prod.py
settings/__init__.py -> local.py
因此__init__.py
是local.py
中的链接(在unix或mklink中为ln)或prod.py
,因此配置仍在project.settings
模块中如果您想使用特定配置,则可以使用环境变量DJANGO_SETTINGS_MODULE
到project.settings.prod
,如果您需要为生产环境运行命令。
文件prod.py
和local.py
:
from .shared import *
DATABASE = {
...
}
并且shared.py
文件在没有特定配置的情况下保持全局。
答案 9 :(得分:0)
如果要保留1个设置文件,并且开发操作系统与生产操作系统不同,可以将其放在settings.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
答案 10 :(得分:0)
这似乎已经得到解答,但是我使用的方法与版本控制相结合如下:
将env.py文件设置在与我也添加到.gitignore的本地开发环境中的设置相同的目录中:
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
我发现这很有用并且更加优雅 - 使用env.py很容易看到我们的本地环境变量,我们可以在没有多个settings.py文件之类的情况下处理所有这些。此方法允许使用我们不希望在生产服务器上设置的各种本地环境变量。通过版本控制使用.gitignore,我们也可以保持所有内容的无缝集成。
答案 11 :(得分:0)
使用settings.py
进行生产。在同一目录中创建settings_dev.py
作为替代。
# settings_dev.py
from .settings import *
DEBUG = False
在开发机上,使用以下命令运行Django应用:
DJANGO_SETTINGS_MODULE=<your_app_name>.settings_dev python3 manage.py runserver
在生产机器上运行,就好像您只有settings.py
而已。
优势
settings.py
(用于生产)完全不知道存在任何其他环境。settings_dev.py
。无需收集散布在settings_prod.py
,settings_dev.py
和settings_shared.py
上的配置。答案 12 :(得分:0)
对于设置文件的问题,我选择复制
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时,将运行__init__py。此时,settings.py in setting1_dir
将替换settings.py in Project
。
如何选择其他环境?
__init__.py
。__init__.py
。__init__.py
读取此变量。为什么要用这种方式?
因为我不喜欢同一目录中的文件太多,所以太多的文件会使其他合作伙伴感到困惑,并且对IDE来说不是很好(IDE无法找到我们使用的文件)
如果您不想看到所有这些详细信息,可以将项目分为两部分。
答案 13 :(得分:0)
我正在使用不同的app.yaml文件来更改Google Cloud App Engine中环境之间的配置。
您可以使用此命令在终端命令中创建代理连接:
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:1433
https://cloud.google.com/sql/docs/sqlserver/connect-admin-proxy#macos-64-bit
文件: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]
答案 14 :(得分:0)
我在生产的工作目录中创建了一个名为“production”的文件。
#settings.py
production = Path("production")
DEBUG = False
#if it's dev mode
if not production.is_file():
INSTALLED_APPS +=[
#apps_in_development_mode,
#...
]
DEBUG = True
#other settings to override the default production settings
答案 15 :(得分:-1)
这是我的解决方案,包括dev,test和prod
的不同环境import socket
[...]
DEV_PC = 'PC059'
host_name = socket.gethostname()
if host_name == DEV_PC:
#do something
pass
elif [...]