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

Django报错:BaseSerializer.is_valid()仅接受1个参数却传入2个

本地无法创建用户的问题修复

此前项目运行正常,因Heroku取消免费套餐,尝试迁移到其他平台后,本地突然无法创建用户,触发错误。相关代码如下:

序列化器代码(serializers/common.py)

from xml.dom import ValidationErr
from rest_framework import serializers
from django.contrib.auth import get_user_model, password_validation
from django.contrib.auth.hashers import make_password
User = get_user_model()

class UserSerializer(serializers.ModelSerializer):

  password = serializers.CharField(write_only=True)
  confirm_password = serializers.CharField(write_only=True)

  def validate(self, data):
    password = data.pop('password')
    confirm_password = data.pop('confirm_password')

    if password != confirm_password:
    raise ValidationErr({ 'confirm_password': 'Does not match the password'})

    password_validation.validate_password(password)

    data['password'] = make_password(password)

    return data
    
  class Meta:
    model = User
    fields = ('id', 'username', 'email', 'password', 'confirm_password')

视图代码(views.py)

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.exceptions import PermissionDenied
from django.contrib.auth import get_user_model
import jwt
User = get_user_model()
from datetime import datetime, timedelta
from jwt_auth.serializers.common import UserSerializer
from django.conf import settings

class RegisterView(APIView):

  def post (self, request):
    create_user = UserSerializer(data=request.data)
    try:
    create_user.is_valid(True)
    create_user.save()
    return Response(create_user.data, status=status.HTTP_201_CREATED)
    except Exception as e:
    print(str(e))
    return Response(e.__dict__ if e.__dict__ else str(e),        status=status.HTTP_422_UNPROCESSABLE_ENTITY)

class LoginView(APIView):
  def post(self, request):
    password = request.data.get('password')
    username = request.data.get('username')
    try:
    user_login = User.objects.get(username=username)
    except User.DoesNotExist:
    raise PermissionDenied('Credentials are incorrect!')
    if not user_login.check_password(password):
    raise PermissionDenied('Credentials are incorrect!')

    dt = datetime.now() + timedelta(days=7)

    token = jwt.encode(
    {
    'sub': user_login.id,
    'exp': int(dt.strftime('%s'))
    },
    settings.SECRET_KEY,
    'HS256'
    )
    print('TOKEN ----->', token)
    return Response({ 'token': token, 'message': f'Welcome back {user_login.username}' })

问题排查与修复方案

1. 异常类导入错误

当前导入的xml.dom.ValidationErr是XML解析专用异常,并非Django REST Framework序列化器应使用的异常类。替换为DRF自带的异常:

# 替换原导入语句
from rest_framework.exceptions import ValidationError

同时将validate方法内的raise ValidationErr改为raise ValidationError。

2. Python缩进错误

Python依赖缩进区分代码块,你的代码多处缩进缺失,直接导致语法或逻辑错误,需修正:

  • validate方法中,if判断后的raise语句需缩进4个空格
  • RegisterView.post的try块内所有代码、except块内代码需缩进
  • LoginView.post的try、except、if块内代码,以及jwt.encode的字典内容需正确缩进

示例修复后的validate方法:

def validate(self, data):
    password = data.pop('password')
    confirm_password = data.pop('confirm_password')

    if password != confirm_password:
        raise ValidationError({ 'confirm_password': '密码不匹配'})

    password_validation.validate_password(password)

    data['password'] = make_password(password)

    return data

3. 视图方法参数优化(可选)

create_user.is_valid(True)虽能触发异常,但更清晰的写法是create_user.is_valid(raise_exception=True),提升代码可读性。

4. JWT时区问题(可选)

datetime.now()使用本地时间,可能导致JWT过期时间计算偏差,建议替换为UTC时间:

dt = datetime.utcnow() + timedelta(days=7)

完成以上修复后,重启本地服务即可正常创建用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:10:55