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

use*_*875 1 django django-views user-registration django-rest-framework

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

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('username', 'password', 'email', )
Run Code Online (Sandbox Code Playgroud)

以下视图之间有什么区别,在创建用户时建议使用哪一个?

查看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)
Run Code Online (Sandbox Code Playgroud)

查看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)
Run Code Online (Sandbox Code Playgroud)

Yeo*_*Yeo 5

这些都不是完美的.但是View A看起来很有前景.

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

要解决此问题,您必须更改Serializer.save()方法的行为.查看文档,Serializer.save()将调用Serializer.create()或者Serializer.update().

总之,我们要覆盖Serializer.create()用户创建和使用.

# 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
Run Code Online (Sandbox Code Playgroud)

  • 因为你做了 [`normalize_email`](https://github.com/django/django/blob/fe914341c83b37fd6aa8fd85620cf49dd2328ab0/django/contrib/auth/base_user.py#L19-L30) 和 [`set_password`](https:// github.com/django/django/blob/fe914341c83b37fd6aa8fd85620cf49dd2328ab0/django/contrib/auth/base_user.py#L83-L84)当[`create_user`](https://github.com/django/django/blob/72f6513ebaa7a3fd43c26 300e9a8c430dc07cdb5/django /contrib/auth/models.py#L140-L147)。 (2认同)
  • @ user2719875我不确定,但我认为它仍然有效,但`init_data`很可能是未经验证的原始数据(`request.DATA`). (2认同)