Python 如何使用django REST Framework(DRF)3创建django用户

Python 如何使用django REST Framework(DRF)3创建django用户,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在尝试使用Django Rest Framework 3.1.1在帖子中创建一个用户。我需要使用内置方法来创建加密密码,因此我尝试在ModelSerializer上重写save方法,但我显然不太了解Django/DRF,无法做到这一点。有没有一个简单的方法来实现这一点 当我尝试下面的代码时,我得到一个错误: unbound method set_password() must be called with User instance as first argument (got unicod

我正在尝试使用Django Rest Framework 3.1.1在帖子中创建一个用户。我需要使用内置方法来创建加密密码,因此我尝试在ModelSerializer上重写save方法,但我显然不太了解Django/DRF,无法做到这一点。有没有一个简单的方法来实现这一点

当我尝试下面的代码时,我得到一个错误:

unbound method set_password() must be called with User instance as first argument (got unicode instance
(取而代之)


尝试这样做:

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

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

尝试这样做:

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

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

由于您使用的是
ModelSerializer
,因此可以覆盖视图中的
perform\u create()
函数,然后为用户设置密码。

DRF提供了这个钩子来添加一些应该在保存对象之前或之后发生的自定义操作

依照

这些覆盖点对于添加行为特别有用 在保存对象之前或之后发生的,例如通过电子邮件发送 确认,或记录更新


由于Django以散列格式存储密码,而不是作为原始密码,因此我们使用Django以散列格式获取原始密码。然后,我们将序列化程序的
validated_data
中的
密码设置为该哈希密码。然后,序列化程序在通过调用
super()

创建用户时会使用此哈希密码,因为您使用的是
ModelSerializer
,因此您可以覆盖视图中的
perform\u create()
函数,然后为用户设置密码。

DRF提供了这个钩子来添加一些应该在保存对象之前或之后发生的自定义操作

依照

这些覆盖点对于添加行为特别有用 在保存对象之前或之后发生的,例如通过电子邮件发送 确认,或记录更新


由于Django以散列格式存储密码,而不是作为原始密码,因此我们使用Django以散列格式获取原始密码。然后,我们将序列化程序的
validated_data
中的
密码设置为该哈希密码。然后,序列化程序在通过调用
super()

set()创建用户时使用此哈希密码。\u密码是一个实例方法,而不是类/静态方法;)set_password是实例方法,而不是类/静态方法;)最好也重写
update
方法,就像这个答案中所说的那样。如果只重写
create
方法,则可能是某些带有
curl
的工具或某些外部应用程序在客户端对API执行
POST
操作时出现
500错误。@bgarcial,我不明白你想说的。请求来自哪个客户机并不重要。如果是帖子,这应该会起作用。最好也覆盖
update
方法,就像回答中所说的那样。如果只重写
create
方法,则可能是某些带有
curl
的工具或某些外部应用程序在客户端对API执行
POST
操作时出现
500错误。@bgarcial,我不明白你想说的。请求来自哪个客户机并不重要。如果是帖子,应该可以。
from django.contrib.auth.hashers import make_password

class MyView(..):

    ...

    def perform_create(self, serializer):
        hashed_password = make_password(serializer.validated_data['password']) # get the hashed password
        serializer.validated_data['password'] = hashed_password 
        user = super(MyView, self).perform_create(serializer) # create a user