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

Django中在GenericViewSet内创建用户并存储加密密码的实现

完善Django ViewSet实现用户创建与密码哈希存储

我来帮你搞定这个DetailedUserViewSet的创建逻辑,核心要记住:绝对不能直接把明文密码存进数据库,Django已经给我们准备好了安全处理密码哈希的方式。

完整的ViewSet代码实现

from rest_framework import status
from rest_framework.response import Response
from django.contrib.auth import get_user_model
from rest_framework.mixins import CreateModelMixin
from rest_framework.viewsets import GenericViewSet
from rest_framework.permissions import AllowAny

# 用get_user_model获取用户模型,适配自定义用户模型的场景
User = get_user_model()

class DetailedUserViewSet(CreateModelMixin, GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (AllowAny,)

    # 原有的__init__方法没有自定义逻辑,完全可以删掉
    def create(self, request, *args, **kwargs):
        # 先用Serializer验证请求数据,比直接操作request.data更安全规范
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        validated_data = serializer.validated_data
        # 把密码从验证数据里单独拎出来,后续单独处理哈希
        password = validated_data.pop('password')
        
        # 创建用户实例,但先不处理密码
        user = User.objects.create(**validated_data)
        # 调用set_password方法处理密码哈希,这是Django官方推荐的安全方式
        user.set_password(password)
        user.save()
        
        # 组装成功响应数据返回
        response_data = {
            'message': 'User created successfully',
            'user': serializer.data
        }
        return Response(response_data, status=status.HTTP_201_CREATED)

关键细节说明

  • 移除多余的__init__方法:你原代码里的__init__只是单纯调用父类方法,没有任何自定义逻辑,留着反而冗余,直接删掉就好。
  • 用Serializer做数据校验:通过serializer.is_valid()验证请求数据,能自动处理字段格式校验、必填项检查等,比直接取request.data更符合DRF的开发规范。
  • set_password的核心作用:这个方法会按照Django配置的PASSWORD_HASHERS(默认是PBKDF2哈希算法)对明文密码进行加密处理,处理后的哈希值才会存入数据库,彻底避免明文存储的安全风险。
  • 适配自定义用户模型:使用get_user_model()获取用户模型,而不是直接导入默认User,这样就算以后换成自定义用户模型,这段代码也不用修改。

额外小提示

如果你的UserSerializer里包含password字段,一定要把它的write_only属性设为True,防止在返回的响应中泄露哈希后的密码:

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = get_user_model()
        fields = ('id', 'email', 'username', 'password') # 根据你的实际需求调整字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:30:31