代码之家  ›  专栏  ›  技术社区  ›  Andrei Taranchenko

覆盖Django中全局设置的最佳方法

  •  1
  • Andrei Taranchenko  · 技术社区  · 17 年前

    我有一个带有多个应用程序(比如,两个)的Django项目,它们都需要不同版本的 中间根 媒体网址 .

    文档确实指定了如何修改特定设置,但这里是我所做的。

    我创建了一个project1/settings.py,

    # project1/settings.py, 
    from django.conf import settings
    
    settings.MEDIA_URL = 'foo'
    settings.MEDIA_ROOT = 'bar'
    

    然后我将该应用程序的init模块修改为 只有 加载模块:

    # project1/__init__.py
    import settings
    

    它起作用了!专用设置文件可以选择性地覆盖全局设置文件。我喜欢的是项目设置文件在一个逻辑位置。

    我的问题是——这种方法是否有任何警告,实现这一点的最佳实践方法是什么?

    2 回复  |  直到 17 年前
        1
  •  4
  •   David Berger    17 年前

    杰瑞特是对的。最佳情况场景:如果您在重新启动服务器后运行一个非常简单的测试,这将起作用。任何其他东西都会破坏它。

    如果您只是使用media_*作为常量,我建议您使用其他常量。如果您真的将它们用于文件字段的默认上载设置,那么您的项目似乎需要您指定路径。那不应该太难。

    您需要克服的两个问题是您当前的方案无法解决:

    1. 每次请求时动态设置变量
    2. 避免恶劣的比赛条件

    1最好通过定制完成 MiddleWare ,可能使用进程请求方法。然而,你想要避免的是

    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
  •  2
  •   Jarret Hardie    17 年前

    我对这应该如何工作有点困惑。您将如何使用每个应用程序代码中的设置?

    # 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)中,它会保持几个子进程的引导和运行,并在请求之间重新使用它们,您的设置中的值将是不可预测的。记住你的代码 初始化 只有在首次导入时才会处理…后续导入不会导致代码重新运行。

    也许我在你的描述中遗漏了一些东西。

    如果您有特定于应用程序的设置,则需要有自己的特定于应用程序的设置,并根据需要对逻辑进行编码以使用它们。