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

DRF中如何通过自定义Token激活用户(设is_active为True)

我来帮你梳理下这个问题哈~首先你的序列化器写法有点问题,get_token方法并不是用来处理激活逻辑的地方,咱们先把这个理顺,再选合适的视图。

一、先修正你的序列化器

你的ActivateUserSerializer里的get_token方法用错场景啦,这个方法是用来序列化输出字段值的,不是处理业务逻辑的。咱们应该把验证手机号和token的逻辑放在序列化器的validate方法里,让它承担数据校验的职责,这样视图层只需要处理业务动作就行:

from rest_framework import serializers
from .models import UserProfile

class ActivateUserSerializer(serializers.Serializer):
    phonenumber = serializers.CharField(required=True)
    token = serializers.CharField(required=True)

    def validate(self, attrs):
        phonenumber = attrs.get('phonenumber')
        token = attrs.get('token')
        
        # 验证手机号对应的用户存在
        try:
            user_profile = UserProfile.objects.get(phonenumber=phonenumber)
        except UserProfile.DoesNotExist:
            raise serializers.ValidationError("该手机号对应的用户不存在")
        
        # 验证token匹配
        if user_profile.first_token != token:
            raise serializers.ValidationError("激活Token不正确")
        
        # 把用户对象存到attrs里,方便视图后续直接使用
        attrs['user_profile'] = user_profile
        return attrs

这里我把序列化器改成了Serializer而非ModelSerializer,因为咱们不需要序列化UserProfile的字段,只是接收手机号和token两个参数,这样更轻量也更贴合需求。

二、选择合适的视图:用APIView实现自定义动作

因为这个激活操作不属于标准的CRUD(创建/读取/更新/删除),而是一个自定义的业务动作,用APIView是最灵活且合适的选择。你只需要继承APIView,实现post方法即可:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import ActivateUserSerializer

class ActivateUserView(APIView):
    def post(self, request):
        serializer = ActivateUserSerializer(data=request.data)
        if serializer.is_valid():
            # 从验证后的参数里取出用户对象
            user_profile = serializer.validated_data['user_profile']
            # 更新激活状态并保存
            user_profile.is_active = True
            user_profile.save()
            return Response({"message": "用户激活成功"}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

最后在你的urls.py里配置这个视图的路由:

from django.urls import path
from .views import ActivateUserView

urlpatterns = [
    # 其他路由...
    path('user/activate/', ActivateUserView.as_view(), name='user-activate'),
]
三、为什么不选其他视图?
  • 如果你用ModelViewSet,也可以通过@action装饰器添加自定义动作,但对于这个简单的激活操作来说,APIView已经足够,没必要引入ViewSet的复杂度。
  • UpdateAPIView需要通过主键(pk)定位用户,但咱们的场景是通过手机号+token来匹配,不符合它的使用逻辑,所以不适合。
额外小建议
  • 可以给first_token字段添加过期时间,避免token长期有效,提升账号安全性。
  • 激活成功后,可以考虑给用户发送短信/邮件通知,优化用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:12:55