загрузить его при запуске:

я есть проект Django, который я хотел бы распространять в общедоступном репозитории, таком как bitbucket или github. Мне бы хотелось, чтобы его было как можно проще установить, поэтому я включаю весь проект, а не только подключаемые приложения. Это означает, чтоsettings.py файл также будет включен.

Как я могу избежать проблемыsetti,ngs.SECRET_KEY быть одинаковым для каждой установки?

Единственныйпросто решение, чтобы пользователь вручную изменилsettings.py?

Должен ли я хранить ключ в базе данных по умолчанию и иметьsettings.py инициализировать его, если он не существует? Это решило бы проблему, но мне интересно, есть ли уже стандартный способ сделать это.

Спасибо!

 S.Lott12 янв. 2011 г., 03:14
Почему вы возитесь с настройками? Всем, кто загружает и устанавливает приложение Django, можно доверять, чтобы исправить настройки.
 Seth12 янв. 2011 г., 05:09
Измените свой секретный ключ на что-то вроде "--- ВСТАВЬТЕ СЕКРЕТНЫЙ КЛЮЧ ЗДЕСЬ ---"
 DylanYoung13 дек. 2017 г., 16:15
Если вы собираетесь хранить его в БД, я бы рекомендовал использовать хеш секретного ключа, а не значение.
 mwcz12 янв. 2011 г., 16:03
Каждому, кто развертывает SSH-сервер, нельзя доверять для создания уникальных закрытых ключей, я не понимаю, почему он должен отличаться для проектов Django. Чем меньше нужно выполнить конфигурацию, тем меньше вероятность ошибок, особенно с чем-то вроде SECRET_KEY, когда вы не можете просто ввести что-то столь же простое, как путь к каталогу.

Ответы на вопрос(8)

Откройте оболочку Django сpython manage.py shell и выполните следующие действия для создания безопасного случайного секретного ключа в Django 2.1:

>>> from django.core.management.utils import get_random_secret_key
>>> get_random_secret_key()
'[GENERATED KEY]'
>>>

Обратите внимание>>> представляет приглашение оболочки и не должно вводиться.

Добавить к чемуКарлес Барробес сказал, что вы можете создать новый ключ, используяметод, который использует Django вstartproject:

from django.utils.crypto import get_random_string

chars = '[email protected]#$%^&*(-_=+)'
get_random_string(50, chars)

Для Django 1.10 и выше, приведенный выше фрагмент кода хорошо обернут в функцию.

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

Ссылка на репозиторий GitHub

 MKaras05 нояб. 2013 г., 03:55
Будет ли работать string.printable?
 Mr. Deathless29 янв. 2014 г., 12:36
@MKaras Любая строка будет работать. Я предполагаю, что входной набор символов ограничен, чтобы повысить читаемость / доступность. Поэтому я бы посоветовал не использоватьstring.printable поскольку он содержит некоторые «сложные» символы, такие как табуляция, новая строка, двоеточие, точка с запятой, пробел и другие.
 alex02 июл. 2015 г., 18:02
Если вы добавите это в свой проект, каждый отдельный процесс Django будет иметь свой ключ. Это означает, например, что если вы запустите несколько одновременных процессов Django (или на отдельных серверах), они получат разные секретные ключи, поэтому материал, подписанный из одного экземпляра, не будет работать на другом. Кроме того, при перезапуске процесса Django вы получите новый секретный ключ, вызывающий аналогичные проблемы.

вдохновленных Two Scoops of Django, так что средний идет примерно так, где 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
Решение Вопроса

Храните секретный ключ в отдельном файле «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....'

Где случайная строка - это сгенерированный ключ, основанный на случайном числе.

Для генерации ключей вы можете использовать предложение Умангаhttps://stackoverflow.com/a/16630719/166761.

 mwcz17 янв. 2011 г., 08:15
Ваш метод чище, чем моя идея хранить ключ в базе данных. Спасибо!
 Nathan Osman06 окт. 2013 г., 00:54
Этот метод также требует, чтобы пользователь загружалsettings.py модуль имеет права на запись в каталог, в котором он находится.
 Carles Barrobés09 окт. 2013 г., 12:48
Хороший вопрос @NathanOsman
 Sync28 июн. 2016 г., 17:36
@JanWrobel Я был озадачен тем, почему вы написали это, пока я не увидел, что сообщение было отредактировано LOL.
 Jan Wrobel11 июл. 2012 г., 16:28
Это полностью сломано, ваш случайный ключ содержит менее 17 бит энтропии. Другими словами, функция генерирует только 100000 уникальных значений ключей, тривиально попробовать их все.

Джанго-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 = '[email protected]#$%^&*(-_=+)'
    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()

вы можете разделить конфигурацию Django на вещи, которые зависят от приложения, и вещи, которые зависят от сервера. Это относится к последней категории.

Существует несколько способов решения проблемы конфигурации конкретного сервера, это обсуждается подробнее вэтот вопрос.

Для этого конкретного случая, используя подход, который я изложил в своем ответе на другой вопрос, я бы поместил заполнитель вsettings_local.py.sample для распространения и во время установки, я бы скопировал этоsettings_local.py и редактировать, чтобы удовлетворить.

 mwcz12 янв. 2011 г., 16:07
Я оставил это в своем первоначальном вопросе, чтобы он был менее многословным, но у меня уже есть файл settings_local.py с MEDIA_ROOT, TEMPLATE_DIRS, SECRET_KEY и т. Д. Я ищу способ автоматизировать генерацию ключа, чтобы люди не могли установить Проект либо забывает генерировать ключи, либо генерирует плохие ключи. Я думаю, что я пойду с сохранением его в базе данных и проверкой settings_local.py на его существование.

django-admin.py startproject --template=path_to_template project_name просто положи{{ secret_key }} в файл настроек шаблона вашего проекта (например, settings.py) какSECRET_KEY = '{{ secret_key }}' и Джанго сгенерирует это для вас.

Предоставьте фиктивный секретный ключ, например:I_AM_A_DUMMY_KEY_CHANGE_MEСоздайте команду управления для создания новой:./manage.py gen_secret_keyВ документации настоятельно советуем пользователям запускать команду как можно скорее.

Ваш ответ на вопрос