我有一个Django项目,我想在像bitbucket或github这样的公共存储库上发布。我希望它尽可能容易安装,所以我要包括完整的项目,而不仅仅是可插拔的应用程序。这意味着还将包含settings.py
文件。
如何避免每次安装settings.SECRET_KEY
相同的问题?
唯一的简单解决方案是让用户手动修改settings.py
吗?
我是否应该将密钥存储在默认数据库中,并且如果它不存在则settings.py
初始化它?这样可以解决问题,但我想知道是否已经有一种标准的方法来做到这一点。
谢谢!
答案 0 :(得分:73)
要添加Carles Barrobés所说的内容,您可以使用the method that Django uses in startproject
生成新密钥:
from django.utils.crypto import get_random_string
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
get_random_string(50, chars)
对于Django 1.10及更高版本,上面的代码片段很好地包含在一个函数中。
from django.core.management.utils import get_random_secret_key
get_random_secret_key()
答案 1 :(得分:39)
我会这样做:
将密钥放在单独的文件“secret_key.py”中。原始安装不存在此文件。在您的settings.py中包含以下内容:
try:
from .secret_key import SECRET_KEY
except ImportError:
SETTINGS_DIR = os.path.abspath(os.path.dirname(__file__))
generate_secret_key(os.path.join(SETTINGS_DIR, 'secret_key.py'))
from .secret_key import SECRET_KEY
您要编写的函数generate_secret_key(filename)
生成一个名为filename
的文件(我们称之为secret_key.py
,与settings.py
在同一个目录中)内容:
SECRET_KEY = '....random string....'
其中随机字符串是基于随机数生成的密钥。
对于密钥生成,您可以使用Umang的建议https://stackoverflow.com/a/16630719/166761。
答案 2 :(得分:11)
使用python manage.py shell
打开Django shell,然后执行以下操作在Django 2.1中创建安全的随机密钥:
>>> from django.core.management.utils import get_random_secret_key
>>> get_random_secret_key()
'[GENERATED KEY]'
>>>
注意:>>>
代表shell提示符,不应键入。
答案 3 :(得分:5)
一般来说,您可以将Django配置划分为特定于应用程序的内容和特定于服务器的内容。这属于后一类。
您可以通过多种方式解决特定于服务器的配置问题,this question中对此进行了详细讨论。
对于这个特定的实例,使用我在对另一个问题的回答中概述的方法,我会在settings_local.py.sample
中放置一个占位符进行分发,在安装过程中,我将其复制到{{1并编辑以适应。
答案 4 :(得分:2)
我会解决这个问题:
I_AM_A_DUMMY_KEY_CHANGE_ME
./manage.py gen_secret_key
答案 5 :(得分:1)
在我的代码中,我有两个级别的设置文件,灵感来自Django的两个Scoops,所以中间的设置就像这样在基础模板中设置了BASE_PRIVATE_DIR。在我的情况下,这是来自django目录../../mysite_private,但在应用程序git下的正常文件的某处:
from .base import *
ALLOWED_HOSTS = ['staging.django.site']
#Allow local override which is per deployment instance. There should probably then be
# an instance git for version control of the production data
try:
import sys
private_path = BASE_PRIVATE_DIR.child('production')
sys.path.append(private_path)
from private_settings import *
except ImportError:
print(" No production overide private_settings.py found. This is probably an error = {}".format(private_path))
# If it doesnt' exist that is fine and just use system and environment defaults
答案 6 :(得分:1)
我在pypi.org上发现了这段代码块,几乎就像Umang的答案一样。
在您的项目目录中运行
{'slug': 'icml2015_liang_language_understanding', 'type': 'Lecture', 'obj_id': 23694, 'video': 1, 'video_id': 23648, 'videos': [1, 2], 'chrome_colors': ['FFFFFF', 'F21F1F'], 'livepipe': '//videolectures.net', 'site_slug': 'vln', 'media_url': 'https://static.videolectures.net/r.1483388978/', 'sentry': '//161ef9a5c3a14af1848399909b890522@sentry.viidea.com/6'}
[('rtmp', 'mp4:v012/01/ae6se7y42if65i27glt3yfanffv5rvtk.mp4'), ('m3u8', 'http://hydro2.videolectures.net/vod/_definst_/mp4:v012/01/ae6se7y42if65i27glt3yfanffv5rvtk.mp4/playlist.m3u8'), ('secure_download', 'http://videolectures.net/site/secure_dl/14f30db64e8184a24b2bb4414dcfdc5d/5f8127f8/ae6se7y42if65i27glt3yfanffv5rvtk/tag=1001866/icml2015_liang_language_understanding_01_400x300_h264.mp4'), ('http', 'http://hydro.ijs.si/v012/01/ae6se7y42if65i27glt3yfanffv5rvtk.mp4')]
('http', 'http://hydro.ijs.si/v012/01/ae6se7y42if65i27glt3yfanffv5rvtk.mp4')
这将生成一个包含随机Django秘密密钥的新文件python manage.py generate_secret_key [--replace] [secretkey.txt]
。在生产设置文件中,将密钥替换为生成的密钥。
或者为了避免对密钥进行硬编码。添加以下代码段,以便当您始终运行该程序时,新的秘密密钥将为您生成一个更新的密钥。
secretkey.txt
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Use a separate file for the secret key
with open(os.path.join(BASE_DIR, 'secretkey.txt')) as f:
SECRET_KEY = f.read().strip()
答案 7 :(得分:0)
如果您使用模板创建新项目,例如django-admin.py startproject --template=path_to_template project_name
只需将{{ secret_key }}
放入项目模板设置文件(例如settings.py),例如SECRET_KEY = '{{ secret_key }}'
,Django就会为您生成
答案 8 :(得分:0)
在此解决方案中,我使用django-dotenv,这是我的项目的依赖项之一,如requirements.txt
中列出的django-dotenv==1.4.1
。这种方法的优点是,对于安装应用程序的每个环境,您都有一个不同的.env
文件。
使用以下内容在utils.py
的同一目录中创建文件settings.py
:
from django.utils.crypto import get_random_string
def generate_secret_key(env_file_name):
env_file = open(env_file_name, "w+")
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
generated_secret_key = get_random_string(50, chars)
env_file.write("SECRET_KEY = '{}'\n".format(generated_secret_key))
env_file.close()
然后按如下方式修改settings.py
文件:
import dotenv
from [project-folder-name] import utils
...
try:
SECRET_KEY = os.environ['SECRET_KEY']
except KeyError:
path_env = os.path.join(BASE_DIR, '.env')
utils.generate_secret_key(path_env)
dotenv.read_dotenv(path_env)
SECRET_KEY = os.environ['SECRET_KEY']
对于那些不使用django-dotenv
的人,您只需将其添加为依赖项并更改manage.py
以在启动时加载它:
import dotenv
if __name__ == "__main__":
dotenv.read_dotenv()
答案 9 :(得分:0)
Carles Barrobés给出了一个很好的答案,但是它不完整,这是我的python 3版本,缺少功能。
from django.core.management.utils import get_random_secret_key
def generate_secret_key (filepath):
secret_file = open(filepath, "w")
secret = "SECRET_KEY= " + "\""+ get_random_secret_key() + "\"" + "\n"
secret_file.write(secret)
secret_file.close()
try:
from .secret_key import SECRET_KEY
except ModuleNotFoundError:
SETTINGS_DIR = os.path.abspath(os.path.dirname(__file__))
generate_secret_key(os.path.join(SETTINGS_DIR, 'secret_key.py'))
from .secret_key import SECRET_KEY
请注意,我将ImportError
更改为ModuleNotFoundError
,并创建了python文件secret_key.py
来像收集变量一样收集SECRET_KEY而不是解析txt文件。