当前位置: 首页 > 后端技术 > Python

二勺Django推荐设置和需求文件设置

时间:2023-03-26 12:44:44 Python

基本原理Django1.8有大约140个配置项,可以通过设置模块进行设置。每次启动Django服务都会初始化settings模块,所以修改settings.py文件后,必须重启Django服务器才能生效。所有的设置文件都要进行版本控制,包括修改日期/时间和配置项注释信息的版本控制DRY,通过importbase_settings继承,避免复制粘贴机密信息,不要在版本控制settings/__init__.py中放置多个设置文件base.pylocal.pystaging.pytest.pyproduction.py和每个settings文件对应一个requirements文件settings文件名local.py,dev.py本地开发环境配置内容,比如DEBUG=True,打开django-debug-toolbar等staging.py为Staging阶段的配置内容test.py为运行测试的配置内容production.py,prod.py为生产环境的配置内容ci.py用于配置持续集成服务器内容方法:pythonmanage.pyshell--settings=twoscoops.settings.local在shell中启动服务pythonmanage.pyrunserver--settings=twoscoops.settings.local设置DJANGO_SETTINGS_MODULE和PYTHONPATH环境变量。如果使用virtualenv,可以在每个环境的激活脚本中设置DJANGO_SETTINGS_MODULE和PYTHONPATH。开发环境中的设置文件示例:#settings/local.pyfrom.baseimport*DEBUG=TrueEMAIL_BACKEND='django.core.mail.backends.console.EmailBackend'DATABASES={"default":{"ENGINE":"django.db.backends.postgresql_psycopg2","NAME":"twoscoops","USER":"","PASSWORD":"","HOST":"localhost","PORT":"",}}INSTALLED_APPS+=("debug_toolbar",)上面的例子有from.baseimport*,这是Django中唯一使用import*的地方。因为我们要覆盖设置文件中的所有命名空间。开发环境也可以有多个设置文件。基本原则是每个设置文件都需要版本控制。可以为不同的开发者创建对应的设置文件,例如:#settings/dev_pydanny.pyfrom.devimport*#设置shortcachetimeoutCACHE_TIMEOUT=30创建后的所有设置文件为:settings/__init__.pybase.pydev.pydev_audreyr.pydev_pydanny.pylocal.pystaging.pytest.pyproduction.py将配置信息与代码分离在代码库中存储SECRET_KEY、APIKEY等信息存在以下问题:这些信息是每个部署特定的值必须更改SECRET_KEY。等效值是配置值,而不是存储在代码库中的代码。任何访问代码库的人都可以看到,大多数PaaS不提供单个服务器的配置功能。解决方案是使用环境变量。使用环境变量存储SECRET_KEY等信息的好处:由于这些敏感信息已经存储在别处,你会毫不犹豫地对每个文件进行版本控制对于每次部署,不需要修改这些配置信息大多数PaaS平台环境推荐使用变量,并提供相应的配置和管理工具。如何在本地设置环境变量在Linux/Macbash中,通过在.bashrc、.bash_profile或.profile文件中添加配置代码来进行配置。如果使用virtualenv,也可以在virtualenv的bin/activate脚本中添加配置代码进行配置:配置代码:$exportSOME_SECRET_KEY=1c3-cr3am-15-yummy$exportAUDREY_FREEZER_KEY=y34h-r1ght-d0nt-t0uch-my-1c3-Win上可以通过cmd.exe中的setx命令配置cr34m,也可以在virtualenv的bin/activate.bat脚本中配置。配置代码:>setSOME_SECRET_KEY1c3-cr3am-15-yummyPowerShell比cmd.exe更强大,Vista及以上版本可用。使用PowerShell设置环境变量:仅针对当前用户:[Environment]::SetEnvironmentVariable("SOME_SECRET_KEY","1c3-cr3am-15-yummy","User")[Environment]::SetEnvironmentVariable("AUDREY_FREEZER_KEY","y34h-r1ght-d0nt-t0uch-my-1c3-cr34m","User")对于这台机器的所有用户:[Environment]::SetEnvironmentVariable("SOME_SECRET_KEY","1c3-cr3am-15-yummy","Machine")[Environment]::SetEnvironmentVariable("AUDREY_FREEZER_KEY","y34h-r1ght-d0nt-t0uch-my-1c3-cr34m","Machine")生产环境环境变量配置示例Configure$herokuconfig:setSOME_SECRET_KEY=onHeroku1c3-cr3am-15-yummy在Python中访问这些配置信息>>>importos>>>os.environ["SOME_SECRET_KEY"]"1c3-cr3am-15-yummy"在设置文件中访问这些配置信息#Topofsettings/production.pyimportosSOME_SECRET_KEY=os.environ["SOME_SECRET_KEY"]处理未设置SECRET_KEY的异常如果没有SECRET_KEY值,上面的access代码会抛出KeyError,项目不会启动。但是这个异常并没有提供有效的提示信息,不利于调试。在settings/base.py中使用以下代码来处理:#settings/base.pyimportos#通常你不应该直接从Django导入任何东西#到你的设置中,但是ImproperlyConfigured是一个例外。fromdjango.core.exceptionsimportImproperlyConfigureddefget_env_variable(var_name):"""获取环境变量或返回异常。"""try:returnos.environ[var_name]exceptKeyError:error_msg="Setthe{}environmentvariable".format(var_name)raiseImproperlyConfigured(error_msg)然后在设置文件中,使用:SOME_SECRET_KEY=get_env_variable("SOME_SECRET_KEY")后,如果没有设置SOME_SECRET_KEY环境变量,会出现如下错误提示:django.core.exceptions.ImproperlyConfigured:SettheSOME_SECRET_KEYenvironmentvariable.manage.py默认情况下,DJANGO_SETTINGS_MODULE指向settings.py。建议多个设置文件使用django-admin,单个设置文件使用manage.py。这两个命令基本是等价的:$django-admin[options]$manage.py[options]当不能设置环境变量时,Apache等使用自己的环境变量,比如上面的方法为系统设置环境变量如果方法无效,敏感信息可以存储在一个不可执行的文件中,并且该文件不受版本控制:生成一个存储敏感信息的文件,格式可以是JSON、Config、YAML或XML添加一个加载器来管理这些信息将文件名添加到.gitignore和.hgignore使用JSON格式生成secrets.json文件:{"FILENAME":"secrets.json","SECRET_KEY":"I'vegotasecret!","DATABASES_HOST":"127.0.0.1","PORT":"5432"}在settings/base.py中添加加载程序以访问此信息:#settings/base.pyimportjson#通常你不应该直接从Django导入任何东西#进入你的设置,但ImproperlyConfigured是一个例外。从django.core.exceptionsimportImproperlyConfigured#JSON-basedsecretsmodulewithopen("secrets.json")asf:secrets=json.loads(f.read())defget_secret(setting,secrets=secrets):""“获取秘密变量或返回显式异常。”“”尝试:返回秘密[setting]除了KeyError:error_msg=“设置{0}环境变量”。format(setting)raiseImproperlyConfigured(error_msg)SECRET_KEY=get_secret("SECRET_KEY")使用多个需求文件每个设置文件需要有一个对应不同配置的需求文件,只安装对应的依赖文件。需求文件示例:requirements/base.txtlocal.txtstaging.txtproduction.txtbase.txt存放全局依赖,如:Django==1.8.0psycopg2==2.6djangorestframework==3.1.1和local。txt,可以在base.txt的基础上添加其他依赖:-rbase.txt#包含base.txt要求filecoverage==3.7.1django-debug-toolbar==1.3.0为连续的ci.txt集成服务器Yes:-rbase.txt#includesthebase.txtrequirementsfilecoverage==3.7.1django-jenkins==0.16.4andproduction.txt基本上和base.txt一样,可能是:-rbase.txt#includesbase.txt需求文件安装用于本地开发:$pipinstall-rrequirements/local.txt用于生产环境:$pipinstall-rrequirements/production.txt需求文件中的所有依赖指定为一个特定的版本,这样可以保证项目更稳定。在设置文件中处理文件路径不要对文件路径进行硬编码使用Unipath进行文件路径处理#在settings/base.py的顶部fromunipathimportPathBASE_DIR=Path(__file__).ancestor(3)MEDIA_ROOT=BASE_DIR.child("media")STATIC_ROOT=BASE_DIR.child("static")STATICFILES_DIRS=(BASE_DIR.child("assets"),)TEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates',DIRS=(BASE_DIR.child("templates"),)},]使用os.path进行文件路径处理#在settings/base.py的顶部fromos.pathimportjoin,abspath,dirnamehere=lambda*dirs:join(abspath(dirname(__file__)),*dirs)BASE_DIR=here("..","..")root=lambda*dirs:join(abspath(BASE_DIR),*dirs)#配置MEDIA_ROOTMEDIA_ROOT=root("media")#配置STATIC_ROOTSTATIC_ROOT=root("collected_static")#静态文件的其他位置STATICFILES_DIRS=(root("assets"),)#ConfiguringTEMPLATE_DIRSTEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates',DIRS=(root("templates"),)},]要了解您的配置与Django的默认配置有何不同,请使用Django的diffsettings命令参考:Django的两勺:Django1.8的最佳实践