Django rest framework使用密码创建用户

2024-05-14 06:27:04 发布

您现在位置:Python中文网/ 问答频道 /正文

使用django rest framework 3和django 1.8

我正在尝试使用django rest framework modelviewsserializer创建用户。问题是DRF使用的default objects.create方法将密码保留为纯文本。

问题是DRF serialzer create方法使用的是objects.createquerysets/#create方法,而不是objects.create_user方法。

来自serializers.py行775的代码

instance = ModelClass.objects.create(**validated_data)

最好的解决办法是什么?我可以重写serializer.create方法以使用objects.user_create而不是objects.create,但它感觉不是正确的解决方案。

其余代码:

from django.contrib.auth.models import User
from rest_framework import viewsets

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'email','password')
        write_only_fields = ('password',)


class UserViewSet(viewsets.ModelViewSet):   
    queryset = User.objects.all()
    serializer = UserSerializer()

Tags: django方法代码fromimportrestobjectscreate
3条回答

除了@aliva的答案中漏掉了serializers.Modelserializer.create()中的功能(这可能很好地保留,例如处理多对多关系),还有一种方法可以保留它。

通过使用user.set_password()方法,还可以正确设置密码,例如:

class UserSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        user = super().create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

这样做的好处是保留了超级类的功能,但缺点是对数据库进行了额外的写操作。决定哪种取舍对你更重要。

编辑:修复语法错误

在序列化程序中还有更好的选项来验证密码

from django.contrib.auth.hashers import make_password

class UserSerializer(serializers.ModelSerializer):
    def validate_password(self, value: str) -> str:
        return make_password(value)

您可以在userserializer中重写create

class UserSerializer(serializers.ModelSerializer):
    # ....

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user

其他解决方案可以重写ViewSet类中的perform_create,也可以在ViewSet类中编写自己的create方法

class UserViewSet(viewsets.ModelViewSet): 
    def create(self, request, format=None):
        # create user here
        # do not call seriailzer.save()

更新:在@freethebees发表评论后,重写perform_create也可以工作,下面是代码片段:

class UserViewSet(viewsets.ModelViewSet, mixins.CreateModelMixin): 
    def perform_create(self, serializer):
        # use User.objects.create_user to create user
        pass

注意: 这个答案给出了3个解决方案,选择一个你认为更适合你的需求和你的项目生态系统的解决方案

注2 我个人更喜欢重写UserViewSet(第二个代码片段)中的create,因为在这里您可以简单地返回您的自定义Response(例如在登录后返回用户配置文件)

相关问题 更多 >