python - DRF 使用序列化器验证正文并序列化响应

标签 python django django-rest-framework

我在 django 中有以下 View ,它登录用户并在使用序列化器序列化用户数据后发回响应。

@api_view(['POST'])
def sign_in(request):
    username = request.data['username']
    password = request.data['password']
    user = authenticate(username=username, password=password)

    if user is not None:
        update_last_login(None, user)  # update the user's last login date
        serializer = UserSignInSerializer(user)
        return Response(serializer.data)

    return Response('Invalid login credentials', status=401)

我不喜欢此 View 的是直接从正文中提取用户名和密码的方式。我想使用相同的序列化器来检查正文是否有效。这是可能的还是我必须创建一个新的序列化器才能验证请求?这是现有的序列化器:

class UserSignInSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email', 'username', 'profile']

最佳答案

您可以使用object level validation来自 django 休息框架。这是一个很好的代码,您可以使用 django rest auth 。我在这里给大家举个例子:

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField(required=False, allow_blank=True)
    password = serializers.CharField(style={'input_type': 'password'})

    def authenticate(self, **kwargs):
        return authenticate(self.context['request'], **kwargs)

    def _validate_username(self, username, password):
        user = None

        if username and password:
            user = self.authenticate(email=email, password=password)
        else:
            msg = _('Must include "username" and "password".')
            raise exceptions.ValidationError(msg)

        return user

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        user = self._validate_username(username, password)
        if user:
            if not user.is_active:
                msg = _('User account is disabled.')
                raise exceptions.ValidationError(msg)
        else:
            msg = _('Unable to log in with provided credentials.')
            raise exceptions.ValidationError(msg)

        attrs['user'] = user
        return attrs

并在 View 中使用此序列化器:

@api_view(['POST'])
def sign_in(request):
    serializer = LoginSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        user = serializer.validated_data['user']
        update_last_login(None, user)  # update the user's last login date
        u_serializer = UserSignInSerializer(user)
        return Response(u_serializer.data)

    return Response(serializer.errors, status=401)

关于python - DRF 使用序列化器验证正文并序列化响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58799576/

相关文章:

python - Django请求中间件在 View 中未生效

python - LSTM 0 准确率

Python str.format 字符串以固定间距开始

python - 如何修复 Python 中的 "Element not interactable"Selenium 错误?

python - Django get_queryset 多选过滤

python - Django Rest框架自定义过滤后端数据重复

python - 如何使用Python脚本解决XML标签没有值的情况下的StopIteration问题

python - Django 抽象模型与简单的 Python 混合与 Python ABCs

python - 找不到 pythonanywhere 中的 css 静态文件

python - 如何在 View 集中获取自定义列表