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

发布于 2024-09-14 03:52:38 字数 953 浏览 6 评论 0原文

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

我发现的大多数多域托管示例都是使用多个 settings.py 文件硬编码到各自的 SITE_ID 来设置的。

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

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)

好奇的是,到目前为止,它已经启动并运行,但还没有经受住实际流量的考验。

I have modified the multihost.py middleware I found at http://effbot.org/zone/django-multihost.htm to set the settings.SITE_ID dynamically, but have some concerns that I may have just left the reservation.

Most examples I have found for multiple domain hosting have been setup with multiple settings.py files hardcoded to their respective SITE_IDs.

Have I created a fix with a fatal flaw here? Will changing this value dynamically bite me on the 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)

For the curious this is up and running so far, but has not stood up to actual traffic.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

热情消退 2024-09-21 03:52:38

简短的官方答案是 你不应该这样做,尽管文档并没有真正解释为什么不这样做。

如果您使用线程服务器,我会担心竞争条件。这应该很容易测试;只需在一个视图中调用 sleep(),然后返回一个带有当前站点名称的 HttpResponse 即可。当第一个视图处于休眠状态时,点击不同域上的不同视图。

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

编辑:我认为你可以使用 禁用 sites 应用程序来“nofollow">RequestSite。 James Bennett 的 django-registration 会实例化一个 RequestSite 对象,该对象从请求对象中提取主机名。

The short, official answer is you're not supposed to do this, though the docs don't really explain why not.

If you're using a threaded server, I'd be concerned about a race condition. This should be quite simple to test; just put a call to sleep() in one view, then return an HttpResponse with the name of the current site. While the first view is sleeping, hit a different view on a different domain.

If you use prefork, I don't imagine that this would cause any problems. I've used this approach with matplotlib, since it's easiest to set graph properties by changing global configuration with matplotlib.rcParams.update(). I use prefork fcgi, so I can safely assume that each request has the whole process to itself (folks, please correct me if I'm wrong).

Edit: I think you can do what you want using RequestSite by disabling the sites application. James Bennett's django-registration, for example, instantiates a RequestSite object in that case, which extracts the hostname from the request object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文