DjangoRestFramework - 注册用户:UserSerializer.save() 和 User.objects.create_user() 之间的区别?

Posted

技术标签:

【中文标题】DjangoRestFramework - 注册用户:UserSerializer.save() 和 User.objects.create_user() 之间的区别?【英文标题】:DjangoRestFramework - registering a user: difference between UserSerializer.save() and User.objects.create_user()? 【发布时间】:2015-07-17 03:16:27 【问题描述】:

假设我想注册一个用户(我正在使用位于 django.contrib.auth.models 中的用户模型)。假设这是我的 serializers.py:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('username', 'password', 'email', )

以下视图有什么区别,在创建用户时推荐哪一个?

查看 A:

def createUser(request):
    if request.method == 'POST':
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

视图 B:

def createUser(request):
    serializer = UserSerializer(data=request.DATA)
    if serializer.is_valid():
        user = User.objects.create_user(
            email = serializer.init_data['email'],
            username = serializer.init_data['username'],
            password = serializer.init_data['password'],
        )

        return Response(serializer.data, status=status.HTTP_201_CREATED)
    else:
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【问题讨论】:

【参考方案1】:

这些都不是完美的。但是View A看起来很有希望。

View A 是一个好的开始,但它是不完整 的解决方案。因为User 的创建不是简单的User.save,而是你必须调用User.create_user 方法。 视图 B 是通过调用User.create_user 创建用户的正确方法,但是,视图包含一个逻辑,实际上应该在Serializer.save() 方法中抽象 .

要解决这个问题,你必须改变Serializer.save() 方法的行为。查看documentation、Serializer.save(),将调用Serializer.create()Serializer.update()

总之,我们必须覆盖 Serializer.create() 来创建用户并使用View A

# File: serializers.py
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User

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

【讨论】:

谢谢。为什么用户创建不仅仅是 User.save()?因为当我这样做时,它可以工作(我假设它不被推荐,但为什么 User.create_user() 是推荐的方法,而不是 User.save()?)。 因为你在create_user 时会使用normalize_emailset_password 啊,谢谢。答案已被接受。在旁注中,我看到您使用了“validated_data['username']”,但在这两个帖子中:***.com/questions/27078272/… 和***.com/questions/22718091/… 他们使用了“init_data['username']”。 init_data 在这种情况下不起作用的任何原因? @user2719875 我不确定,但我认为它仍然可以工作,但init_data 很可能是未经验证的原始数据 (request.DATA)。

以上是关于DjangoRestFramework - 注册用户:UserSerializer.save() 和 User.objects.create_user() 之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法在 Django 路由器中注册“.as_view()”(使用 djangorestframework-simplejwt)?

DjangoRestFramework学习三之认证组件权限组件频率组件url注册器响应器分页组件

如何保护 Django Rest Framework 中注册和登录的 API?

Django Rest Framework:在 ViewSet 中注册多个序列化程序

[Django Rest Framework]:如何在注册页面上添加 phone_number 字段?

Python 3 & Django Rest Framework - 如何查询 M-1-M 模型?