DRF如何通过关联cardModel获取对应用户,解决QuerySet精确查询报错
问题修复方案
报错根因
你当前的错误是视图层的查询逻辑错误导致的,核心问题有2个:
- 调用
User.objects.filter()返回的是结果集合(QuerySet类型),而Token.objects.get_or_create()的user参数要求传入单个用户实例,把结果集直接传入就会触发你遇到的ValueError - 反向关联查询的语法错误:你通过
card_numbers(用户关联卡号的反向关系名)直接传入卡号值过滤,不符合Django ORM的跨表查询规则,查询结果不符合预期。
修复代码
因为你设置了card_number字段是唯一值,最简洁的查询逻辑是直接查卡号对应的卡实例,再取关联的用户,不用单独查用户表,修复后的视图代码如下:
# 注意先确认导入路径匹配你的项目结构 from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.permissions import AllowAny from rest_framework.authtoken.models import Token from .models import cardModel from .serializers import CheckCard class CheckCardAPI(APIView): permission_classes = [AllowAny] serializer_class = CheckCard def post(self,request,*args,**kwargs): serializer = self.serializer_class(data=request.data) # 先做序列化校验,避免非法参数输入 serializer.is_valid(raise_exception=True) card_number = serializer.validated_data.get('card_number') # 因为card_number是唯一值,直接查对应卡实例 try: card = cardModel.objects.get(card_number=card_number) except cardModel.DoesNotExist: return Response({'error':'card is not registered'},status=status.HTTP_404_NOT_FOUND) # 直接从卡实例取关联的用户,不用再单独查用户表 user = card.user # 处理卡号没有绑定用户的边界情况(你模型里user字段允许为空) if not user: return Response({'error':'current card is not bound to any user'}, status=status.HTTP_400_BAD_REQUEST) tokens, created = Token.objects.get_or_create(user=user) return Response({'token':tokens.key},status=status.HTTP_200_OK)
其他优化建议
- 你的
CheckCard序列化器继承的是普通Serializer,Meta配置里的user字段不需要声明,你没有用到该字段的序列化输出,保留card_number即可 - 模型类命名建议遵循Python大驼峰规范,
cardModel改成CardModel可读性更好 - 模型里
card_number用IntegerField存储有风险,如果卡号是16位或者更长,超过IntegerField的最大值(2147483647)会报错,建议改成CharField存储卡号
内容的提问来源于stack exchange,提问作者Georgia
相关产品推荐
相关产品推荐

