Django API查询UUID外键匹配指定值的所有对象返回404如何解决
404错误原因
- 核心原因为路由匹配顺序冲突:Django的路由规则是从上到下匹配,你将
include(router.urls)放在自定义路由的前面,ContactViewSet作为ModelViewSet会自动生成/contacts/<pk>/的单条联系人检索路由。当你访问/contacts/[公司UUID]时,请求会优先匹配到ContactViewSet的retrieve接口,框架会尝试用你传入的公司UUID去Contact表查询主键对应的联系人数据,自然找不到对应记录,返回404。 - 次要原因为过滤写法不严谨(非本次报错直接原因):
get_queryset中直接用外键对象匹配传入的UUID值,虽不会直接触发报错,但存在类型匹配的潜在风险。
解决方案
方案1:调整路由顺序(推荐)
将自定义的公司联系人查询路由放在router包含的路由之前,让Django优先匹配你定义的规则:
urlpatterns = [ # 自定义路由前置 path('contacts/<uuid:company>/', CompanyContactsListView.as_view(), name='contacts'), path('', include(router.urls)), ]
方案2:修改自定义路由前缀(避免路由冲突)
如果不想调整路由顺序,也可以给自定义路由设置独立前缀,和默认的联系人路由完全区分开:
urlpatterns = [ path('', include(router.urls)), # 更换为独立的路径前缀 path('company-contacts/<uuid:company>/', CompanyContactsListView.as_view(), name='contacts') ]
可选优化:完善查询逻辑
优化get_queryset的过滤逻辑,显式指定外键ID字段匹配,避免潜在的类型问题:
class CompanyContactsListView(generics.ListAPIView): serializer_class = ContactSerializer def get_queryset(self): company_uuid = self.kwargs['company'] return Contact.objects.filter(company_id=company_uuid)
额外规范修正(不影响接口逻辑)
公司模型的复数命名不符合英文规范,可修正为:
class Meta: verbose_name = "Company" verbose_name_plural = "Companies"
内容的提问来源于stack exchange,提问作者Thomas Mack
相关产品推荐
相关产品推荐

