Skip to content

Async serializer validation #60

@michaelurban

Description

@michaelurban

Issue Description

BaseSerializer does not implement an async version of validate or is_valid.


Why is this needed?

In my case I'm validating an email/password pair with an async call to a database.


Solution

It would make sense to implement avalidate, ais_valid, and arun_validation in BaseSerializer.


Hackjob

A quick copy-paste to async implementation.

from django.core.exceptions import ValidationError as DjangoValidationError

from rest_framework.fields import empty
from rest_framework.exceptions import ValidationError

from rest_framework import serializers as drf_serializers
from adrf import serializers as adrf_serializers

__all__ = ("AsyncValidationSerializer",)


class AsyncValidationSerializer(adrf_serializers.BaseSerializer):
    async def ais_valid(self, *, raise_exception=False):
        assert hasattr(self, "initial_data"), (
            "Cannot call `.is_valid()` as no `data=` keyword argument was "
            "passed when instantiating the serializer instance."
        )

        if not hasattr(self, "_validated_data"):
            try:
                self._validated_data = await self.arun_validation(self.initial_data)
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

        if self._errors and raise_exception:
            raise ValidationError(self.errors)

        return not bool(self._errors)

    async def arun_validation(self, data=empty):
        (is_empty_value, data) = self.validate_empty_values(data)
        if is_empty_value:
            return data

        value = self.to_internal_value(data)
        try:
            self.run_validators(value)
            value = await self.avalidate(value)
            assert value is not None, ".validate() should return the validated data"
        except (ValidationError, DjangoValidationError) as exc:
            raise ValidationError(detail=drf_serializers.as_serializer_error(exc))

        return value

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions