Django REST Framework多URL参数映射:用户名替代ID报错
问题分析与解决方案
咱们一步步拆解你遇到的问题,先搞懂根源,再给出修复方案:
错误的核心原因
你看到的 invalid literal for int() with base 10: 'username' 报错,本质是RetrieveAPIView的默认查询逻辑和你传入的参数类型不匹配:
- Example模型里的
user是外键,Django默认会用user_id(整数类型)来做关联查询 - 你URL里传的是字符串类型的用户名,但RetrieveAPIView默认会把URL参数当作模型主键(整数)去匹配,自然就出现了字符串转整数的报错
另外,你重写的get_object方法没生效,是因为查询条件写错了:你用user=user来查询,第一个user是外键字段,Django会默认匹配用户的id(整数),而第二个user是URL里的用户名(字符串),完全不匹配,所以还是会触发默认查询逻辑导致报错。
具体修复步骤
1. 修正get_object的查询条件
把外键查询改成按用户名匹配,用Django的双下划线查询语法user__username:
class ExampleDetailAPIView(RetrieveAPIView): queryset = Example.objects.all() serializer_class = ExampleDetailSerializer def get_object(self): user_username = self.kwargs.get('user') slug = self.kwargs.get('slug') # 明确按用户名匹配外键关联的用户 return Example.objects.get(user__username=user_username, slug=slug) # 修正拼写错误:serilizer → serializer(不修复的话上下文传参可能失效) def get_serializer_context(self, *args, **kwargs): return {'request': self.request}
2. 保留现有URL配置
你的URL规则是正确的,不需要修改:
urlpatterns = [ url(r'^api/(?P<user>\w+)/(?P<slug>[\w-]+)/$', ExampleDetailAPIView.as_view(), name='example'), ]
3. 验证序列化器与模型方法
你的序列化器和模型的get_api_url方法是正确的,已经在生成URL时传入了用户名,只要视图的查询逻辑修复,就能正常生成带用户名的API链接。
补充:为什么之前的get_object没解决问题?
因为Django外键字段的默认查询行为是匹配关联模型的主键(也就是用户的id),你写user=user时,Django会自动解析为user_id=user,也就是尝试把用户名(字符串)当作用户ID(整数)去查询,这显然会失败。必须用user__username明确指定按用户名字段查询。
内容的提问来源于stack exchange,提问作者laa
相关产品推荐
相关产品推荐

