我有一个 Web 应用程序,它将根据 url 的第一段返回用户 id,很像 Twitter:
http://www.myapplication.com/user-name-goes-here/
它也可以更深入,如下所示:
http://www.myapplication.com/user-name-goes-here/news/article_1/
为了分解网站,我使用以下 URL 路由技术:
(r'^(?P<slug>\w+)/', include('myapp.sites.urls')),
这将进一步将用户路由到正确的页面,但就目前情况而言,我必须在每个视图中查询数据库,以便根据第一个视图获取 user_id url 段。我希望以某种方式自动执行此操作,这样我就不必每次都使用相同的代码来膨胀我的视图...我的解决方案是创建一些中间件来检查 url 段并在未找到时返回 404:
from django.http import Http404
class DomainMiddleware(object):
def process_request(self, request):
from myapp.sites.models import Sites
dname = request.path.split('/')[1]
if not dname:
return
try:
d = Sites.objects.get(domain__exact=dname)
except Sites.DoesNotExist:
raise Http404
return
这有效,但它试图解析每个请求,甚至是图像、图标等的请求。
我的问题是:有没有一种方法可以在每次页面加载时运行此查询,而不会用额外的代码阻塞我的视图?如果中间件是解决方案,我如何修改我的代码,使其不包含每个请求,而仅包含那些成功路由 URL 的请求?
希望有人可以帮忙!
I have a web application which will return a user id based on the first segment of the url, much like Twitter:
http://www.myapplication.com/user-name-goes-here/
It can go deeper too, like so:
http://www.myapplication.com/user-name-goes-here/news/article_1/
In order to break the site down, I am using the following URL routing technique:
(r'^(?P<slug>\w+)/', include('myapp.sites.urls')),
This will then further route the user to the correct page, but as it stands I am having to query the database in every view in order to obtain the user_id based on the first url segment. I was hoping to somehow automate this so I don't have to bloat my views with the same code each time... my solution was to create some middleware which checks the url segment and returns a 404 if its not found:
from django.http import Http404
class DomainMiddleware(object):
def process_request(self, request):
from myapp.sites.models import Sites
dname = request.path.split('/')[1]
if not dname:
return
try:
d = Sites.objects.get(domain__exact=dname)
except Sites.DoesNotExist:
raise Http404
return
This works, but it's trying to parse EVERY request, even those to images, favicons etc.
My question is thus; Is there a way to run this query on every page load without clogging up my views with extra code? If middleware is the solution, how can I modify my code so that it doesn't include EVERY request, only those to successfully routed URLs?
Hope someone can help!
发布评论
评论(1)
Django 服务器不应该处理对静态内容 URL 的请求 - 当然也不应该在生产环境中,在生产环境中您需要运行不同的 Web 服务器来处理该请求,因此这不应该成为问题。
但是,如果您希望它仅针对成功路由的 URL 运行,也许您最好在中间件中使用 process_view 而不是 process_request ? http://docs.djangoproject.com/en/dev /topics/http/middleware/#process-view
process_view 在视图级别而不是请求级别工作,并提供一个 view_func 参数,您可以检查该参数,以便您的代码在 django.views.static 时不会运行.serve 视图用于在开发过程中提供静态媒体服务。
无论发生什么情况,如果要在每个视图上使用该数据库调用,您都应该缓存该数据库调用。
The Django server shouldn't be processing requests for static content URLs - certainly not in production anyway, where you'd have a different web server running to handle that, so this shouldn't be an issue there.
But if you say you'd like this to run for only sucessfully routed URLs, maybe you'd be better of using process_view rather than process_request in your middleware? http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-view
process_view works at view level rather than request level, and provides a view_func argument which you can check so that your code doesn't run when it's the django.views.static.serve view used for serving static media during development.
Whatever happens you should defs be caching that database call if it's going to be used on every view.