Django URL与视图过滤问题:访问/collection/...时404页面未找到
解决Django按name过滤City记录的404问题
看起来你混淆了**查询参数(Query Parameters)和路径参数(Path Parameters)**的用法,这是导致404错误的核心原因。我们来逐一分析问题并给出对应解决方案:
问题根源
你尝试的两种方案都是配置了路径参数(把name放在URL路径里,比如/city/Bor),但实际请求的却是查询参数格式的URL(/city?name=Bor),Django无法匹配到对应的路由规则,所以返回404。
另外还有两个小问题:
- 方案1中用
path()写正则表达式是错误的——Django的path()不支持正则,正则路由需要用re_path()(或url(),是re_path()的别名)。 - 如果是过滤返回多条记录,应该用
ListAPIView而非RetrieveAPIView(RetrieveAPIView用于获取单个对象,返回多个结果会报错)。
方案一:使用查询参数过滤(/collection/city?name=Bor)
如果你想保持用?name=xxx的方式过滤,按以下步骤修改:
- URL配置保持不变:
# urls.py path('city/', views.TestListCity.as_view())
- 视图改用
ListAPIView,并从request.GET获取参数:
# views.py from rest_framework import generics class TestListCity(generics.ListAPIView): serializer_class = TestListCitySerializer queryset = City.objects.all() def get_queryset(self): # 从查询参数中获取name值 name = self.request.GET.get('name') queryset = super().get_queryset() # 如果name存在,过滤结果 if name: queryset = queryset.filter(name=name) return queryset
这样请求http://192.168.99.100:8080/collection/city?name=Bor就能返回所有name匹配的City记录了。
方案二:使用路径参数获取单个记录(/collection/city/Bor)
如果你想通过URL路径传递name(比如/city/Bor),适合用RetrieveAPIView(但要确保name字段在数据库中是唯一的):
- 修改URL配置为路径参数:
# urls.py path('city/<str:name>/', views.TestListCity.as_view())
- 视图配置
lookup_field为name:
# views.py from rest_framework import generics class TestListCity(generics.RetrieveAPIView): serializer_class = TestListCitySerializer queryset = City.objects.all() lookup_field = 'name' # 指定用name字段作为查询条件
⚠️ 注意:必须确保City模型的name字段是唯一的(可以在模型中添加unique=True),否则RetrieveAPIView会因为匹配到多个对象而抛出MultipleObjectsReturned异常。
此时请求URL应为http://192.168.99.100:8080/collection/city/Bor,就能返回对应的单个City记录。
内容的提问来源于stack exchange,提问作者Veljko
相关产品推荐
相关产品推荐

