Django 主机名中间件被缓存
我创建了一个 Django 项目来管理两个共享一些后端代码的独立站点。这两个网站都位于不同的应用程序内。每个应用程序都有自己的 models.py、views.py、模板等...
为了能够对不同的主机名做出不同的反应,我创建了一个 URLconf 中间件:
class HostnameBasedUrlconfMiddleware(object):
"""This middleware parses the hostname from the request, and selects the
urlconf accordingly.
To set a custom urlconf according to the current hostname, add an URLCONF
dictionary to your settings.py file.
URLCONF = {
'example.com': 'urls_example',
'example.dev': 'urls_dev',
'admin.example.dev': 'apps.admin.urls'
}
If the hostname is not found in the URLCONF dictionary, the default
ROOT_URLCONF setting will be used.
"""
def process_request(self, request):
# Decide which urlconf to use. Fallback is to use the ROOT_URLCONF
# as defined in the settings.py file.
try:
hostname = request.META['HTTP_HOST']
request.urlconf = settings.URLCONF[hostname]
except (KeyError, AttributeError):
pass
return None
一开始这似乎有效,但后来我意识到某种缓存一定正在发生。
当启动服务器并请求站点A时,它就会出现。如果我随后请求站点 B,站点 A 就会出现。有时(但并非总是),经过几次重新加载后,站点 B 最终会出现。重新启动服务器并请求站点 B 后,它会显示出来,但现在站点 A 将显示站点 B 的内容。
内置开发服务器和gunicorn 都发生过这种情况。
我尝试使用curl请求该网站以避免浏览器缓存,没有区别。
我还怀疑这可能是某种模板名称冲突,但所有模板都位于各自模板文件夹内唯一命名的子文件夹内。
我没有安装 memcached,也没有使用任何缓存中间件。
可能是什么问题?是否有一些内部自动缓存正在进行?
I created a Django project to manage two separate sites that share some backend code. Both of the sites are inside separate apps. Each app has its own models.py, views.py, templates etc...
To be able to react differently to different hostnames, I created an URLconf middleware:
class HostnameBasedUrlconfMiddleware(object):
"""This middleware parses the hostname from the request, and selects the
urlconf accordingly.
To set a custom urlconf according to the current hostname, add an URLCONF
dictionary to your settings.py file.
URLCONF = {
'example.com': 'urls_example',
'example.dev': 'urls_dev',
'admin.example.dev': 'apps.admin.urls'
}
If the hostname is not found in the URLCONF dictionary, the default
ROOT_URLCONF setting will be used.
"""
def process_request(self, request):
# Decide which urlconf to use. Fallback is to use the ROOT_URLCONF
# as defined in the settings.py file.
try:
hostname = request.META['HTTP_HOST']
request.urlconf = settings.URLCONF[hostname]
except (KeyError, AttributeError):
pass
return None
This seemed to work at first, but then I became aware that some kind of caching must be happening.
When starting the server and requesting site A, it would show up. If I then request site B, site A shows up. Sometimes (but not always), after several reloads, site B would finally show up. After restarting the server and requesting site B, it would show up, but now site A would show site B content.
This happened with the builtin devserver as well as with gunicorn.
I tried to request the site with curl to avoid browser caching, no difference.
I also suspected it could be some kind of template name collision, but all templates are inside a uniquely named subfolder inside their respective template folders.
I don't have memcached installed and I'm not using any caching middleware.
What could be the problem? Is there some internal automatic caching going on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下是在 urlconf 中替换的代码(至少适用于 1.3):
django.core.handlers.base:
因此,看起来它只是直接使用来自
request 的值。 urlconf
。并且您的中间件直接设置request
值。我会安装 django-debug-toolbar 来确认是否
request.urlconf
的值不是 a) 正在设置或 b) 正在更改。为了绝对确定,为什么不暂时将代码更改为类似以下内容:
然后您可以查看调试工具栏中的值(或只是将它们输出到模板中)以查看可能发生的情况。
但是,我建议您不要使用中间件,而只需为每个域设置不同的 settings.py 文件。然后,在您使用的任何 Web 服务器中,将每个服务器设置为使用自己的 .wsgi 文件,该文件指向其自己的设置文件,如下所示:
settings_a.py:
settings_b。 py
Here is the code in question that substitutes in the urlconf (for 1.3 at least):
django.core.handlers.base:
So, it looks like it's just using the value directly from
request.urlconf
. And your middleware is setting therequest
value directly.I'd install django-debug-toolbar to confirm whether or not the value for
request.urlconf
is a) being set or b) being changed along the way.To make absolutely sure, why not change the code temporarily to something like:
Then you can look at the values in the debug toolbar (or just output them in a template) to see what might be going on.
However, I would suggest instead of using middleware, that you simply set up different settings.py files for each domain. Then, in whatever web server you're using, set each one up to use its own .wsgi file, which points to its own settings file, like so:
settings_a.py:
settings_b.py