可以安全地从 Django 中的中间件修改 settings.SITE_ID 吗?
我修改了在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
简短的官方答案是 你不应该这样做,尽管文档并没有真正解释为什么不这样做。
如果您使用线程服务器,我会担心竞争条件。这应该很容易测试;只需在一个视图中调用
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 anHttpResponse
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 aRequestSite
object in that case, which extracts the hostname from the request object.