例行:如有错误,敬请指正;
目录
2.1在django根目录,新建一个config.py文件;
3.2在根目录创建.env文件和对应环境的.env.{环境文件}
3.4引用配置,例如 Django 设置文件中,使用 config 对象来获取 .env 文件中的变量
一、背景
由于开发环境、测试环境、正式环境;对应的数据库、IP、root路径、log地址等都不同;于是想到抽一个配置文件出来,放这些配置,再每次启动时,将环境作为输入,来启动项目加载对应环境的变量。
但由于在不同环境中启动的命令就不同,配置jenkins命令时还得做区分;于是干脆直接配置一个IP和环境的对应关系,直接通过IP判断当前的环境;再直接加载运行;无需进行其他的代码部署区分;
二、实现过程
2.1在django根目录,新建一个config.py文件;
2.2编辑config.py文件
import socket
class Config(object):
DEBUG = False
# get attribute
def __getitem__(self, key):
return self.__getattribute__(key)
class DevelopmentConfig(Config):
ROOT='home/{XX}'
PG_HOST='xx.xx.xxx.xx:5432'
PG_USER='postgres'
PG_PWD='pwd'
LOG_FILE='/home/{XX}/logs/map_target_slice.log'
class TestConfig(Config):
ROOT='home/{XX}'
PG_HOST='xx.xx.xxx.xx:5432'
PG_USER='postgres'
PG_PWD='pwd'
LOG_FILE='/home/{XX}/logs/map_target_slice.log'
class ProductionConfig(Config):
ROOT='home/{XX}'
PG_HOST='xx.xx.xxx.xx:5432'
PG_USER='postgres'
PG_PWD='pwd'
LOG_FILE='/home/{XX}/logs/map_target_slice.log'
def curEnv():
hostname=socket.gethostname()
localIP = socket.gethostbyname(hostname + ".local")
return localIP
# IP to env
envs = {
'xx.xx.xxx.xx':'dev',
'xx.xx.xxx.xxx':'dev',
'xx.xx.xxx.xxxx':'test',
'xx.xx.xxx.xxxxx':'pro',
}
# env to class
mapping = {
'dev': DevelopmentConfig,
'pro': ProductionConfig,
'test': TestConfig
}
# load env config
localIP = curEnv()
env = envs[localIP]
config = mapping[env]()
2.3调用配置中的变量
from config import config
PG_HOST=config.PG_HOST
三、其他方法
在写出上述方法前,还通过newbing进行了其他方法的探索,最终比较下来,还是选择使用一个文件的方法来实现;这里是ai提供的建议方法:
以下是一个示例:
3.1在项目中安装库
pip install python-decouple django-environ
3.2在根目录创建.env文件和对应环境的.env.{环境文件}
.env #放ip和环境的对应关系
SECRET_KEY=mysecretkey
DEBUG=True
DATABASE_URL=postgres://user:password@localhost/mydatabase
PRODUCTION_IPS=192.168.1.100, 192.168.1.101
TESTING_IPS=192.168.1.102, 192.168.1.103
.env.production
.env.testing
.env.development
以上文件中放入具体的环境变量
3.3在根目录创建env.py
文件
添加一个 get_environment
函数,用于根据当前 IP 地址来自动判断当前的环境。例如:
import os from decouple
import config from environ
import Env
# 加载 .env 文件中的变量
env = Env()
env.read_env() # 获取当前 IP 地址
def get_ip_address():
ip = os.environ.get('REMOTE_ADDR', '')
if not ip:
ip = os.environ.get('HTTP_X_FORWARDED_FOR', '')
return ip
# 根据 IP 地址来判断当前环境
def get_environment():
ip = get_ip_address()
if ip in config('PRODUCTION_IPS', cast=lambda v: [i.strip() for i in v.split(',')]):
return 'production'
elif ip in config('TESTING_IPS', cast=lambda v: [i.strip() for i in v.split(',')]):
return 'testing'
else:
return 'development'
# 根据当前环境加载对应的配置文件
environment = get_environment()
if environment == 'production':
env_file = '.env.production'
elif environment == 'testing':
env_file = '.env.testing'
else:
env_file = '.env.development'
env.read_env(env_file)
# 设置 Django 设置模块的环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
3.4引用配置,例如 Django 设置文件中,使用 config
对象来获取 .env
文件中的变量
from decouple import config
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
DATABASES = { 'default': config('DATABASE_URL', default='sqlite://db.sqlite3', cast=db_url), }