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

Django Rest Framework新用户注册需管理员激活问题求助

解决DRF注册用户is_active不生效及未激活用户登录限制问题

一、修复is_active=False不生效的问题

你的代码核心问题有两个:

  1. RegisterSerializer的create方法缩进错误,被嵌套在了Meta类内部,导致该方法完全不会被执行;
  2. User.objects.create_user会直接将用户数据保存到数据库,修改is_active字段后必须调用user.save()才能把更改同步到数据库。

修正后的serializer.py代码:

class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id','username','password')
        extra_kwargs = {
            'password':{'write_only': True}
        }

    # 将create方法移到RegisterSerializer类下,而非Meta内部
    def create(self, validated_data):
        user = User.objects.create_user(validated_data['username'], password=validated_data['password'])
        user.is_active = False
        user.save()  # 必须调用save()完成字段更新
        return user


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
        extra_kwargs = {
            'password':{
                'write_only': True
            }
        }

二、阻止未激活用户登录

根据你使用的认证方式,选择对应的实现方案:

方案1:基于DRF自带Token认证

重写ObtainAuthToken视图,添加is_active状态检查:

# views.py
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework import status

class CustomAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        if not user.is_active:
            return Response({'error': '账户未激活,请联系管理员'}, status=status.HTTP_401_UNAUTHORIZED)
        # 生成或获取用户令牌
        from rest_framework.authtoken.models import Token
        token, created = Token.objects.get_or_create(user=user)
        return Response({'token': token.key, 'user_id': user.pk, 'username': user.username})

然后在urls.py中替换默认认证路由:

from django.urls import path
from .views import CustomAuthToken

urlpatterns = [
    # 其他路由...
    path('api-token-auth/', CustomAuthToken.as_view(), name='api_token_auth'),
]

方案2:基于JWT认证(以djangorestframework-simplejwt为例)

重写Token获取序列化器,添加is_active校验:

# serializer.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        if not self.user.is_active:
            raise serializers.ValidationError("账户未激活,请联系管理员")
        return data

在settings.py中配置使用自定义序列化器:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

SIMPLE_JWT = {
    'TOKEN_OBTAIN_SERIALIZER': 'your_app.serializers.CustomTokenObtainPairSerializer',
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:58:24