【问题标题】:How to alter django settings based on current request?如何根据当前请求更改 django 设置?
【发布时间】:2011-09-05 06:18:16
【问题描述】:

我正在从一个 django 实例运行多个站点,并希望该框架最终能够为来自一个或多个安装的数百个站点提供服务。

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

我还应该补充一下,这主要是为了让我没有编写的第三方应用程序受益,所以我不想到处添加装饰器或类似的东西,因为那会打乱我的升级路径。

所以:

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

【问题讨论】:

  • 为什么不从数据库生成 WSGI 文件?这对我来说似乎更理智。
  • 有趣。但我在想,就可扩展性而言,如果整个应用程序与站点无关,这样我就可以配置一个新服务器,部署我的代码,每个服务器只会为它收到请求的任何站点提供页面。跨度>
  • 当你说猴子补丁时,你是在修改中间件中的django.conf.settings吗?

标签: django


【解决方案1】:

这个模块 - django-tupperware 可以满足您的要求:https://bitbucket.org/jiaaro/django-tupperware/ 试试看吧。

【讨论】:

    【解决方案2】:

    永远不要即时更改设置。您无法预测应用程序有一天会如何部署,并且在大多数情况下,项目会以......有趣的方式失败。

    【讨论】:

    • 那么我有什么选择呢?我需要从数据库中获取设置并在调用其他应用程序之前应用它们。
    • 不要那样做。甚至不要尝试。而是在架构中进行更多规划。
    • 嗯,该应用程序的重点是用户可以创建自己的站点并将一些设置存储在数据库中......您有什么建议?
    • 我坚持同样的事情@Paul。我尝试重写一个 database.py 文件(该文件又作为模块导入到 settings.py )。该行为在生产中不稳定。 4 次中有 2 次选择旧的数据库设置。解决方案:重新启动服务器 - 但在生产中如何? :(
    • 这是意见,不是答案,应该是评论!
    【解决方案3】:

    如果你真的想拥有数百个随时动态重新配置的站点,你可以尝试使用 Djangos django/conf/__init__.py 来为框架的其余部分提供设置。您可以根据请求及其主机字段的方式对其进行更改。或者你至少会遇到很多有趣的失败。

    【讨论】:

      【解决方案4】:

      我对这个问题的解决方案是提供每个请求、所有设置并使用中间件即时更新它们,我该怎么做? 比较简单: 这是完成所有工作的中间件

      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'
      

      但这并不重要,因为您可能只想更改具有可用请求对象的上下文的设置。

      【讨论】:

        猜你喜欢
        • 2023-03-29
        • 2011-03-23
        • 2021-07-09
        • 2017-11-27
        • 2021-12-17
        • 1970-01-01
        • 2015-02-08
        • 2012-03-07
        • 1970-01-01
        相关资源
        最近更新 更多