DRF使用序列化程序验证正文并序列化响应



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

@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)

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

class UserSignInSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['first_name', 'last_name', 'email', 'username', 'profile']

您可以使用django rest框架中的object level validation。这里有一个很好的代码,您可以从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

并在视图中使用此序列化程序:

@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)

最新更新