Django中无前缀斜杠带查询参数的路由请求处理问题
Django路由处理带特定查询参数请求的解决方案
嘿,我来帮你搞定这个Django路由的小难题!其实核心问题在于:Django的URLconf只匹配URL中?之前的路径部分,带查询参数的/foo和普通的/foo路径完全一致,所以路由本身没法直接区分这两种请求。下面给你几个实用的方案:
1. 优先推荐:在视图内区分查询参数
这也是你自己考虑过的思路,其实这是最符合HTTP规范的做法——查询参数的作用本来就是对同一资源做特殊过滤或处理,而不是用来区分不同的资源路径。
你可以把所有/foo的GET请求都路由到同一个视图,然后在视图里检查查询参数的内容来分逻辑处理:
from django.views.generic import View from django.http import HttpResponse class FooView(View): def get(self, request, *args, **kwargs): # 获取bar参数的值,没有的话返回None bar_param = request.GET.get('bar') if bar_param == '-capacity': # 处理带bar=-capacity的请求逻辑 return HttpResponse("处理带特定参数的foo请求") else: # 处理普通的/foo请求逻辑 return HttpResponse("普通的foo请求")
对应的路由规则就很简洁:
urlpatterns = [ url(r'^foo$', views.FooView.as_view()), ]
这个方案的好处:
- 不用维护多个路由规则,逻辑集中在一个视图里,后期修改更方便
- 完全兼容现有请求的URL格式,不需要调整前端代码
- 符合RESTful设计原则,同一资源用同一个路径,用查询参数区分不同的处理逻辑
2. 可选方案:调整URL结构(把参数放到路径中)
如果你的业务场景确实需要通过路径来明确区分这两种请求,也可以把参数整合到URL路径里,比如:
urlpatterns = [ # 处理普通/foo请求 url(r'^foo$', views.NormalFooView.as_view()), # 处理带特定参数的请求,路径改为/foo/-capacity url(r'^foo/-capacity$', views.CapacityFooView.as_view()), ]
不过这个方案需要前端把请求从/foo?bar=-capacity改成/foo/-capacity,如果已经有现有业务在使用旧URL,可能需要添加重定向规则来兼容。
3. 关于你之前尝试的路由规则的说明
你之前用的url(r'^foo(.*)$', ...)其实过于宽泛了——它会匹配所有以foo开头的路径,比如/foobar、/foo123这些完全不相关的请求,很容易导致路由冲突,不建议使用。而url(r'^foo/(.*)$', ...)要求路径必须包含/foo/后缀,和你的目标请求/foo?bar=-capacity的路径(没有后缀斜杠)不匹配,所以才会出现需要处理两个URL的情况。
综合来看,第一种方案是最省心也最符合规范的,推荐你采用!
内容的提问来源于stack exchange,提问作者Braden Holt
相关产品推荐
相关产品推荐

