Lorenzo Ang
Lorenzo Ang

Reputation: 1318

Serializer `validate()` not getting called on `is_valid()` on POST

I want to create a non class-based form to facilitate uniform logging in by users across all front-end apps. Currently, it looks like this

My serializer class:

class EmployeeLoginSerializer(serializers.Serializer):
    username = serializers.CharField(min_length=6)
    password = serializers.CharField(min_length=6)

    def validate_credentials(self, attrs):
        print('validating')
        try:
            emp: Employee = Employee.objects.get(username=attrs['username'])
            if crypto.verify_password(attrs['password'], emp.password_hash):
                return attrs
        except Exception:
            raise serializers.ValidationError("Incorrect username or password")
        raise serializers.ValidationError('Incorrect username or password')

My view class:

class TestView(APIView):
serializer_class = EmployeeLoginSerializer

def get(self, request, *args, **kwargs):
    return Response({'Message': 'Get works'})

def post(self, request, *args, **kwargs):
    print(request.POST)
    serializer = self.serializer_class(data=request.POST)
    if serializer.is_valid():
        return Response({'Message': 'Credentials were correct'})

My issue is that serializer.is_valid() doesn't seem to be calling on validate automatically. I know I could just call serializer.validate() manually but all the docs and questions on StackOverflow seem to show validate() being called by is_valid() automatically so I get that feeling that that wouldn't be the best practice. Is there something I'm missing?

Upvotes: 3

Views: 2366

Answers (1)

JPG
JPG

Reputation: 88509

The is_valid() method will call validate() method of the serializer and validate_FIELD_NAME() methods.

In your code, the validate_credentials() seems a regular class method which won't detect by DRF since the credentials isn't a field on the serializer.

Upvotes: 3

Related Questions