2009-03-25 2 views
1

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

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

Я создал project1/settings.py,

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

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

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

# project1/__init__.py 
import settings 

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

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

ответ

4

Jarret является правильным. Лучший сценарий: это будет работать, если вы запустите очень простой тест после перезапуска сервера. Почти что-нибудь еще сломает его.

Если вы просто используете 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.

+1

Дэвид, решения промежуточного программного обеспечения выглядят довольно интересно, но, если можно, я нашел только одно предостережение - если у вас есть управляемые пользовательские команды, которым необходим доступ к настройкам, получение настроек скорее всего, окажется сложным. Помня о своем ответе, я пошел с настройкой переопределений по каждому запросу, от чего-то вроде [PREFIX] _MEDIA_ROOT. Это позволяет мне писать команды manage.py, которые не зависят от каких-либо обманов. –

+0

Это должно сработать. Название mangling не всегда рекомендуется стиль. Вы можете объединить это с вашим оригинальным решением: иметь один MEDIA_ROOT, а затем в project1/__ init__.py создать произвольную переменную conf, например settings.PROJECT_NAME = "project1". Тогда ваша логика просмотра может ссылаться на request.media_root, и вы управляете .py функции могут восстановить путь из settings.MEDIA_ROOT и settings.PROJECT_NAME. –

+0

Андрей "свободный диапазон" Таранченко снова прав –

2

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

# 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 будет обработан только тогда, когда он будет импортирован в первый раз ... последующий импорт не приводит к повторному запуску кода.

Возможно, мне что-то не хватает в вашем описании.

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

+0

Не думал об этом. Я тестировал только один проект :) –

Смежные вопросы