如何根据当前请求更改django设置?

时间:2011-05-31 07:12:13

标签: django

我正在从一个django实例运行多个站点,并期望该框架最终从一个或多个安装中服务数百个站点。

我需要根据当前请求修补一些django设置。我已经编写了一些中间件来修补设置,但我需要在中间件被调用之前修补这些设置,因为其他应用程序没有采取猴子修补的更改(即应用程序运行然后中间件运行所以应用程序不要不要使用猴子修补设置。

我还应该补充说,这主要是为了第三方应用程序的好处,我还没写过,所以我不想再添加装饰器或类似的东西,因为这会搞砸我的升级路径。 / p>

所以:

  • 如何在应用的 init .py文件中访问当前请求?
  • 应用的 init .py会在每次请求时调用一次还是只调用一次?如果它只有一次,我怎么能这样做,所以我可以按照请求操作一次设置?
  • 做这种猴子修补是否安全?我知道它使代码更加不透明,但我不想在每个站点使用不同的wsgi文件,因为我想允许用户编辑其中一些设置并让我的猴子补丁来自数据库。
  • 是否有更好的解决方案可以将某些设置存储在数据库中?

4 个答案:

答案 0 :(得分:5)

此模块 - django-tupperware可以满足您的要求:https://bitbucket.org/jiaaro/django-tupperware/ 试一试。

答案 1 :(得分:1)

从未动态更改设置。您无法预测应用程序有一天可能会被部署,并且在大多数情况下,项目将以有趣的方式失败。

答案 2 :(得分:1)

如果你真的想拥有数百个将一直动态重新配置的网站,你可以尝试使用Djangos django/conf/__init__.py来为框架的其余部分提供设置。您可能能够以某种方式更改它,这取决于请求及其主机字段。或者你至少会得到许多有趣的失败。

答案 3 :(得分:0)

我对这个问题的解决方案是给每个请求,所有设置并使用中间件动态更新它们,我该怎么做? 很简单: 这是完成所有工作的中间件

from django.conf import settings

class DumpObject: pass

class Settings(object):
    def process_request(self,request):
        request.settings = DumpObject()
        for setting in dir(settings):
            if not setting.startswith('__'):
                setattr(request.settings, setting, getattr(settings,setting))

DumpObject就在那里,所以我可以使用object.property表示法,它可能是一本字典,但我希望在语法上保持一些相似之处。 这假设您的设置名称都不以__开头,这是一个公平的假设。 因此,如果我想覆盖特定的设置,我不会保留一个设置文件,我在这个中间件中这样做。像这样:

class Settings(object):
    def process_request(self,request):
        request.settings = DumpObject()
        for setting in dir(settings):
            if not setting.startswith('__'):
                setattr(request.settings, setting, getattr(settings,setting))

         if 'mydomain' in str(request.host): #this is thanks to django-hosts project
            request.settings.GOOGLE_ANALYTICS_ID = '89298393-238'

当然,这并没有考虑到以旧方式访问设置的问题     来自django.conf导入设置

settings.GOOGLE_ANALYTICS_ID = 'the value in settings.py'

但它确实无关紧要,因为您可能只想更改具有请求对象的上下文的设置。