Лучший способ переопределить глобальные настройки в Django - PullRequest
1 голос
/ 25 марта 2009

У меня есть проект Django с несколькими приложениями (скажем, двумя), и для обоих нужны разные версии MEDIA_ROOT и MEDIA_URL .

В документации указано, как изменить конкретную настройку, но вот что я сделал.

Я создал проект1 / settings.py,

# project1/settings.py, 
from django.conf import settings

settings.MEDIA_URL = 'foo'
settings.MEDIA_ROOT = 'bar'

Затем я изменил модуль инициализации этого приложения, чтобы только загрузить модуль:

# project1/__init__.py
import settings

Это работает! Специализированный файл настроек удачно перезаписывает глобальный, выборочно. Что мне нравится в этом, так это то, что файл настроек проекта находится в логическом месте.

Мой вопрос: есть ли у этого подхода какие-либо предостережения, и каков наилучший способ достижения этого?

Ответы [ 2 ]

4 голосов
/ 25 марта 2009

Джаррет прав. В лучшем случае: это будет работать, если вы запустите очень простой тест после перезапуска сервера. Почти все остальное сломает это.

Если вы просто используете MEDIA_ * в качестве констант, я бы рекомендовал использовать некоторую другую константу. Если вы действительно используете их для настроек загрузки по умолчанию для полей файлов, похоже, что ваш проект потребует от вас указать путь. Это не должно быть слишком сложно.

Необходимо преодолеть две проблемы, которые не решаются в вашей текущей схеме:

  1. Динамическая установка переменных при каждом запросе
  2. Как избежать плохих условий гонки

1 лучше всего выполнить с помощью пользовательского MiddleWare , вероятно, с помощью метода process_request. Однако, чего вы хотите избежать, так это

settings.MEDIA_URL = 'foo'

злоупотребление глобальной переменной. Это вызовет проблему 2. Поскольку process_request позволяет передавать объект HttpRequest, я рекомендую поместить туда информацию о переменной:

class MyMiddleWare:
    def process_request(self,request):
        media_root = #some logic to parse request.path
        request.media_root = media_root

Ваши статические ссылки должны будут ссылаться на request.media_root.

2 голосов
/ 25 марта 2009

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

# project1/view.py
import settings
print settings.MEDIA_URL

или

# project1/view.py
from django.conf import settings
print settings.MEDIA_URL

В первом случае это, вероятно, не будет работать, поскольку импортируемые вами настройки - это project1.settings, который сам по себе не имеет атрибута MEDIA_URL.

Во втором случае разве вы не попадете в состояние гонки? В зависимости от того, какое приложение было загружено последним, оно в последний раз перезаписывает атрибут в глобальном объекте settings. Это может работать в некоторых случаях, когда вы просто работаете локально и запускаете сервер, а затем сразу переходите к представлению в том или ином приложении, но на долго работающем сервере, таком как Apache, который поддерживает загрузку и запуск нескольких дочерних процессов. - используя их из запроса в запрос, значения в ваших настройках будут непредсказуемыми. Помните, что код в init будет обрабатываться только при первом его импорте ... последующий импорт не приводит к повторному запуску кода.

Может быть, я что-то упустил в вашем описании.

Если у вас есть настройки для конкретного приложения, вам нужно будет иметь свои собственные настройки для конкретного приложения и кодировать свою логику, чтобы использовать их соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...