可以安全地修改Django中间件的settings.SITE_ID吗?

时间:2010-08-12 01:56:59

标签: django django-middleware django-sites

我修改了我在http://effbot.org/zone/django-multihost.htm找到的multihost.py中间件来动态设置settings.SITE_ID,但有些担心我可能刚刚离开预订。

我发现多个域托管的大多数示例都设置了多个settings.py文件,这些文件硬编码到各自的SITE_ID。

我是否在这里创建了一个带有致命缺陷的修复程序?将a *动态地改变这个值。

from django.conf import settings
from django.contrib.sites.models import Site

class MultiHostMiddleware:

    def process_request(self, request):
        try:
            host_raw = request.META["HTTP_HOST"]
            colon = host_raw.find(':')
            if colon > -1:
                host = host_raw[0:colon]
            else:
                host = host_raw

            s = Site.objects.get(domain=host)
            if s:
                settings.SITE_ID = s.id

        except KeyError:
            pass # use default urlconf (settings.ROOT_URLCONF)

对于好奇的人来说,到目前为止已经开始运行,但是还没有达到实际的流量。

1 个答案:

答案 0 :(得分:6)

简短的官方答案是you're not supposed to do this,尽管文档并没有真正解释原因。

如果您使用的是线程服务器,我会担心竞争状况。这应该很容易测试;只需在一个视图中调用sleep(),然后返回一个HttpResponse,其中包含当前网站的名称。当第一个视图正在休眠时,在另一个域上点击不同的视图。

如果您使用prefork,我不认为这会导致任何问题。我已经将这种方法与matplotlib一起使用,因为通过使用matplotlib.rcParams.update()更改全局配置来设置图形属性是最简单的。我使用prefork fcgi,所以我可以放心地假设每个请求都有自己的整个过程(伙计们,如果我错了,请纠正我)。

修改:我认为您可以通过禁用 sites应用使用RequestSite来执行您想要的操作。例如,James Bennett的django-registration在这种情况下实例化一个RequestSite对象,它从请求对象中提取主机名。