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

Django登录接口测试返回400状态码,断言失败排查

问题原因及解决方案

核心问题

测试用例返回400的根本原因是:你在测试中用format='json'发送JSON格式的数据,但视图里的LoginForm是基于request.POST初始化的——Django默认只会将表单编码格式(application/x-www-form-urlencoded或multipart/form-data)的请求体解析到request.POST中,JSON格式的请求体不会被解析到这里,导致表单验证失败,最终触发返回400的分支。

而你手动调用接口正常,是因为前端发送的是表单编码格式的数据,request.POST能正确获取到参数,表单验证通过。


解决方案

方案1:修改测试代码(推荐,符合视图现有逻辑)

去掉format='json',改用表单编码格式发送数据,同时确保测试用户已提前创建:

def setUp(self):
    # 初始化测试用户,确保数据库中存在该用户
    self.user = User.objects.create_user(username='voter1', password='123')

def test_login(self):
    data = {'usuario_email': 'voter1', 'password1': '123'}
    # 去掉format='json',默认使用表单编码格式发送请求
    response = self.client.post('/authentication/login/', data)
    self.assertEqual(response.status_code, 200)
    message = response.json().get('message')
    self.assertEqual(message, 'Autentificación correcta')

若需明确指定请求头,也可以写成:

response = self.client.post(
    '/authentication/login/', 
    data, 
    content_type='application/x-www-form-urlencoded'
)

方案2:修改视图,同时支持JSON和表单编码请求

如果需要视图兼容两种请求格式,可在视图中先判断请求类型,解析JSON数据后再初始化表单:

import json
from django.http import JsonResponse
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from .forms import LoginForm

def user_login(request):
    if request.method == 'POST':
        # 处理JSON格式请求
        if request.content_type == 'application/json':
            try:
                data = json.loads(request.body)
            except json.JSONDecodeError:
                return JsonResponse({'error': 'JSON格式错误'}, status=400)
            form = LoginForm(data)
        # 处理表单编码格式请求
        else:
            form = LoginForm(request.POST)
        
        if form.is_valid():
            cd = form.cleaned_data
            usuario_email = cd.get('usuario_email')
            password1 = cd.get('password1')
            user = None
            if usuario_email and '@' in usuario_email:
                user = User.objects.filter(email=usuario_email).first()
            else:
                user = User.objects.filter(username=usuario_email).first()

            if user is not None:
                user = authenticate(username=user.username, password=password1)
                if user is not None and user.is_active:
                    login(request, user)
                    print("Usuario logueado correctamente")
                    return JsonResponse({'message': 'Autentificacion correcta'})
                else:
                    return JsonResponse({'message': 'Cuenta desactivada o credenciales inválidas'})
            else:
                return JsonResponse({'message': 'Inicio de sesión inválido'})

    return JsonResponse({'error': 'Solicitud incorrecta'}, status=400)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:57:29