使用邮箱作为主键调用DRF接口发起GET请求返回404错误排查
问题原因分析
1. 主键映射逻辑不匹配
你在CustomerBookings模型中设置customer字段为primary_key=True,这意味着CustomerBookings表的主键实际存储的是关联的Customer表的主键值,并非直接存储邮箱地址:
- 如果你的
Customer表用的是默认自增id作为主键,那么CustomerBookings的主键就是数字id,传入邮箱字符串自然匹配不到记录 - 即便你特意把
Customer表的主键设为邮箱字段,也需要额外配置DRF的查询规则才能匹配关联字段
2. DRF视图未配置正确的查找规则
DRF的ModelViewSet默认使用lookup_field = 'pk'直接匹配当前模型的主键,如果你要通过关联表的邮箱字段查询,需要手动修改视图配置:
class BookingAPIViewSet(viewsets.ModelViewSet): # 先修正序列化器类名错误,你原有配置中写的CustomerBookingsSerializer不存在,实际定义的是BookingSerializer serializer_class = BookingSerializer queryset = CustomerBookings.objects.all() # 这里的customer__email对应Customer模型中邮箱的字段名,按你实际字段名调整即可 lookup_field = 'customer__email'
同时需要调整urls.py中对应路由的匹配规则,允许接收邮箱格式的参数:
# 替换原有默认的主键匹配路由,适配邮箱格式 path('bookings/booking/<str:email>/', BookingAPIViewSet.as_view({'get': 'retrieve'}))
3. URL编码的潜在问题
你请求地址里的%40是@的URL编码,绝大多数场景下DRF会自动解码,但如果你的路由规则限制了特殊字符输入,也可能导致参数匹配失败返回404,需要确认路由参数允许@等特殊字符。
快速验证方法
你可以先调用http://127.0.0.1:8000/bookings/booking/拿到全量条目,查看返回结果中单条记录的主键值格式,如果是数字id,就说明你的Customer表主键确实是自增id而非邮箱,传邮箱查询必然失败。
内容的提问来源于stack exchange,提问作者Cl0ud-l3ss
相关产品推荐
相关产品推荐

