分发具有唯一密钥的Django项目

分发具有唯一密钥的Django项目,django,Django,我有一个Django项目,我想将其发布在公共存储库(如bitbucket或github)上。我希望它尽可能容易安装,所以我包括完整的项目,而不仅仅是可插拔的应用程序。这意味着也将包括settings.py文件 如何避免设置的问题。每个安装的密钥都相同 是让用户手动修改设置.py的唯一简单解决方案吗 我是否应该将密钥存储在默认数据库中,并在不存在时对其进行settings.py初始化?这将解决问题,但我想知道是否已经有一个标准的方法来做到这一点 谢谢 一般来说,您可以将Django配置分为特定于应

我有一个Django项目,我想将其发布在公共存储库(如bitbucket或github)上。我希望它尽可能容易安装,所以我包括完整的项目,而不仅仅是可插拔的应用程序。这意味着也将包括
settings.py
文件

如何避免
设置的问题。每个安装的密钥都相同

是让用户手动修改
设置.py
的唯一简单解决方案吗

我是否应该将密钥存储在默认数据库中,并在不存在时对其进行
settings.py
初始化?这将解决问题,但我想知道是否已经有一个标准的方法来做到这一点


谢谢

一般来说,您可以将Django配置分为特定于应用程序的配置和特定于服务器的配置。这属于后一类

有许多方法可以解决特定于服务器的配置问题,详细内容将在中讨论


对于这个特定的例子,使用我在回答另一个问题时概述的方法,我会在
settings\u local.py.sample
中放置一个占位符进行分发,在安装过程中,我会将其复制到
settings\u local.py
并根据需要进行编辑。

我会这样做:

将密钥保存在单独的文件“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....'
其中,random string是基于随机数生成的密钥

对于密钥生成,您可以使用Umang的建议。

要添加所述内容,您可以使用以下方法生成新密钥:


对于Django 1.10及更高版本,上面的代码片段很好地封装在一个函数中

from django.core.management.utils import get_random_secret_key
get_random_secret_key()

我会这样解决问题:

  • 提供一个虚拟密钥,如:
    I\u AM\u a\u dummy\u key\u CHANGE\u ME
  • 创建管理命令以生成新命令:
    /manage.py gen\u secret\u key
  • 在文档中,强烈建议用户尽快运行该命令

在我的代码中,我有三个级别的设置文件,灵感来自两个Django勺子,所以中间的一个类似这样,在基本模板中设置了BASE_PRIVATE_DIR。在我的例子中,这是来自django目录.././mysite\u 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

如果您使用template创建一个新项目,比如
django-admin.py startproject--template=path\u to\u template project\u name
只需将
{{secret\u key}}
放入项目模板设置文件(例如settings.py),比如
secret\u key={{secret key}“
和Django将为您生成它。

在我使用的这个解决方案中,它是我项目的依赖项之一,如
requirements.txt
中所列,如
Django dotenv==1.4.1
。这种方法的优点是,对于安装应用程序的每个环境,都有一个不同的
.env
文件

settings.py
的同一目录中创建具有以下内容的文件
utils.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()

使用
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提示符,不应键入

编辑:这里的一些答案建议从Django设置文件本身自动生成一个包含密钥的文件。由于几个原因,这不适合于生产环境。首先,未来部署到新机器将创建不匹配的密钥。其次,您需要格外小心,以确保其他程序或用户无法读取该文件。由于这些原因,在生产机器上存储机密作为环境变量通常是可取的和常见的做法

给出了一个很好的答案,但它是不完整的,这是我的python 3版本,其中缺少的函数可以工作

从django.core.management.utils导入get\u random\u secret\u密钥
def生成密钥(文件路径):
机密文件=打开(文件路径,“w”)
secret=“secret\u KEY=“+”\”“+获取\u随机\u secret\u KEY()+“\”“+”\n
秘密文件。写入(秘密)
secret_file.close()文件
尝试:
from.secret\u key导入secret\u key
除ModuleNotFoundError外:
设置\u DIR=os.path.abspath(os.path.dirname(\uu文件\uu))
生成密钥(os.path.join(SETTINGS\u DIR,'secret\u key.py'))
from.secret\u key导入secret\u key

请注意,我更改了
ModuleNotFoundError
ImportError
,并创建了python文件
secret\u key.py
,以将secret\u key像变量一样收集起来,而不是解析txt文件。

我发现这段代码的工作原理几乎与Umang的答案类似

就在您的项目目录中运行

python manage.py生成密钥[--replace][secretkey.txt]
这将生成一个包含随机Django密钥的新文件
secretkey.txt
。在生产设置文件中,使用生成的密钥替换密钥

或者为了避免对密钥进行硬编码。添加以下代码段,以便始终运行程序时,新密钥将为您生成更新的密钥

导入操作系统
BASE_DIR=os.path.dirname(os.path.dirname
>>> from django.core.management.utils import get_random_secret_key
>>> get_random_secret_key()
'[GENERATED KEY]'
>>>