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

Django用户创建密码未加密排查:为何未调用UserManager?

问题根源与解决方案

你遇到的核心问题是:Django的ModelSerializer默认不会调用你自定义的UserManager方法,而是直接使用模型的create()方法,跳过了密码加密的逻辑。下面详细拆解原因和修复步骤:

1. 为什么没有调用UserManager?

Django的ModelSerializer默认的create()实现是这样的(简化版):

def create(self, validated_data):
    return self.model.objects.create(**validated_data)

它直接调用了模型的objects.create(),而不是你自定义的create_user()方法,自然不会触发UserManager里的set_password()加密步骤,导致密码明文存储。

另外,你在UserProfileViewSet里重写的post方法也没必要——ModelViewSet已经自带了标准化的create方法来处理POST请求,自定义post反而容易绕开框架的正确流程。

2. 修复步骤

步骤1:重写Serializer的create方法

修改serializers.py,让它主动调用你自定义的create_user方法:

from rest_framework import serializers
from .models import UserProfile

class UserProfileSerializer(serializers.ModelSerializer):
    phone = serializers.CharField(required=True, allow_blank=False)
    password = serializers.CharField(required=True, allow_blank=False, write_only=True)

    class Meta:
        model = UserProfile
        fields = '__all__'
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        # 调用UserManager的create_user方法,触发密码加密
        return UserProfile.objects.create_user(
            phone=validated_data['phone'],
            password=validated_data['password']
        )

步骤2:移除ViewSet中自定义的post方法

ModelViewSet已经内置了处理POST请求的create方法,完全覆盖了你自定义的post逻辑,而且更符合DRF的规范。修改views.py:

from rest_framework.viewsets import ModelViewSet
from .serializers import UserProfileSerializer
from .models import UserProfile

class UserProfileViewSet(ModelViewSet):
    serializer_class = UserProfileSerializer
    queryset = UserProfile.objects.all()

    # 删掉下面这段自定义的post方法
    # def post(self, request):
    #     serializer = self.serializer_class(data=request.data)
    #     serializer.is_valid(raise_exception=True)
    #     serializer.save()
    #     return Response(data=serializer.data, status=HTTP_200_OK)

3. 验证修复效果

创建新用户后,检查数据库的password字段:

  • 加密后的密码会以pbkdf2_sha256$开头(Django默认加密算法),而不是明文密码。
  • 同时,UserManager的_create_user方法会被正确调用,执行user.set_password(password)逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:04:30