You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DRF APITestCase测试用户资料API时遇错误求助

问题解决:Django REST Framework测试中的两个错误修复

一、修复TypeError: 'BasePermissionMetaclass'对象不可迭代

问题原因

  1. 视图类的authentication_classes定义错误:LoginView和RegisterView中使用(JWTAuthentication)(小括号),Python会将其解析为单个对象而非可迭代的列表/元组,DRF尝试迭代权限类时触发类型错误。
  2. 注册/登录视图无需JWT认证:注册、登录是开放接口,不需要提前进行JWT认证,否则未登录用户无法访问。

代码修改

修改views.py中的LoginView和RegisterView:

from rest_framework_simplejwt.tokens import RefreshToken

class LoginView(APIView):
    # 移除JWT认证装饰器与类内错误定义
    def post(self, request, *args, **kwargs):
        serializer = LoginSerializers(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        # 保留正确的JWT生成逻辑,移除多余的login和Token创建代码
        refresh = RefreshToken.for_user(user)
        access_token = str(refresh.access_token)
        return Response({
            'message': 'Successful login',
            'access_token': access_token,
            'refresh_token': str(refresh),
        }, status=status.HTTP_200_OK)


class RegisterView(APIView):  
    # 移除JWT认证相关定义
    def post(self, request):
        serializer = RegisterSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response({
                'message': 'successfully registered',  
            }, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

同时修正HomeownerProfileView的authentication_classes定义:

class HomeownerProfileView(APIView):
    permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
    # 改为列表形式,确保可迭代
    authentication_classes = [JWTAuthentication]
    serializer_class = HomeownerProfileSerializer
    # ... 其他方法

二、修复资料测试返回404状态码

问题原因

  1. 视图get方法参数错误:未接收request和路由参数,且尝试从kwargs获取username,但路由定义的参数是user_id。
  2. 视图返回值错误:直接返回数据库对象,而非DRF的Response对象,未使用序列化器处理数据。
  3. 测试URL路径错误:请求URL缺少开头的/,导致路径解析异常。
  4. 未关联HomeownerUser实例:测试仅创建User,但HomeownerProfileSerializer对应HomeownerUser模型,需创建关联实例。

代码修改

1. 修改views.py中的HomeownerProfileView

from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404

class HomeownerProfileView(APIView):
    permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
    authentication_classes = [JWTAuthentication]
    serializer_class = HomeownerProfileSerializer

    # 修正get方法参数,接收request与路由参数
    def get(self, request, *args, **kwargs):
        user_id = self.kwargs['user_id']
        user = get_object_or_404(User, id=user_id)
        # 获取关联的HomeownerUser实例
        homeowner_profile = get_object_or_404(HomeownerUser, user=user)
        serializer = self.serializer_class(homeowner_profile)
        return Response(serializer.data, status=status.HTTP_200_OK)

2. 修改test_profile.py

from rest_framework.test import APITestCase, APIClient
from rest_framework import status
from ..models import User, HomeownerUser


class HomeownerProfileTest(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user(username='test_homeowner', password='password321', email='test@example.com')
        # 创建关联的HomeownerUser实例
        self.homeowner_profile = HomeownerUser.objects.create(user=self.user)
        
    def test_profile(self):
        client = APIClient()
        client.login(username='test_homeowner', password='password321')
        # URL添加开头的/,确保路径正确
        response = client.get(f'/api/users/{self.user.id}/profile/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

3. 确保HomeownerUser模型关联正确

from django.db import models
from django.contrib.auth.models import User

class HomeownerUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    profile_pic = models.ImageField(upload_to='profiles/', blank=True, null=True)
    street_address = models.CharField(max_length=255, blank=True)
    homeowner_city = models.CharField(max_length=100, blank=True)
    homeowner_state = models.CharField(max_length=2, blank=True)
    homeowner_zip_code = models.CharField(max_length=10, blank=True)

内容的提问来源于stack exchange,提问作者Corveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 09:42:02