Django Urls如何配置可选查询参数以支持无season参数的请求
Django可选路由参数配置解决方案
1. 调整urls.py配置(二选一即可)
方案1:注册两条路由指向同一视图
直接注册带season参数和不带season参数的两条规则,都匹配同一个视图类:
app_name = 'main' urlpatterns = [ path('',include(router.urls)), # 带season参数的路由 path('player_id=<str:player>%season_id=<str:season>',views.MatchesList.as_view()), # 不带season参数的路由 path('player_id=<str:player>',views.MatchesList.as_view()) ]
方案2:用re_path配置可选参数正则
如果不想写重复路由,可以用正则路由将season部分标记为可选:
from django.urls import re_path app_name = 'main' urlpatterns = [ path('',include(router.urls)), re_path(r'^player_id=(?P<player>[^%]+)(%season_id=(?P<season>[^%]+))?$', views.MatchesList.as_view()) ]
2. 调整views.py参数获取逻辑
不能直接从kwargs中强制取season参数,需要设置默认值为None,同时修正权限配置的语法问题(元组单个元素需要加逗号,否则不会被识别为权限集合):
class MatchesList(generics.ListAPIView): serializer_class = MatchesSerializer permissions = (IsAuthenticated,) def get_queryset(self): player = self.kwargs['player'] # 从kwargs中取season,不存在则默认返回None season = self.kwargs.get('season', None) if season is None: queryset = Matches.objects.filter(player=player).all() else: queryset = Matches.objects.filter(player=player,season=season).all() return queryset
补充建议:实际开发中更推荐用查询参数(即
?player_id=xxx&season_id=xxx的形式)传递这类筛选参数,不需要配置多路由,直接从self.request.query_params中取值即可,扩展性更强。
内容的提问来源于stack exchange,提问作者Tomas Garrido
相关产品推荐
相关产品推荐

