Overriding Django-Rest-Framework serializer is_valid method

I have a quick question about overriding is_valid. Self is rest_framework.serializers.ModelSerializer. I'm trying to figure out if there is a better way to modify internal data than reading / writing to the data._kwargs property. I know I can get the pre-validation of the data by calling self.get_initial (). But I would also like to be able to write data. The goal here is to change the Image Data, if not formatted correctly, to the format our models accept so that our API is more flexible. I know there may be other ways to achieve my goals, but my general question is, "Is there a good method for setting data in the serializer before calling is_valid ()?" because this applies to other matters as well. Thank!

def is_valid(self, raise_exception=True):
    imageHandler = ImageHandler()
    if "member_profile" in self._kwargs["data"]:
        if "profile_image" in self._kwargs["data"]["member_profile"]:
            self._kwargs["data"]["member_profile"]["profile_image"] = imageHandler.convertImage(
                self._kwargs["data"]["member_profile"]["profile_image"])
    else:
        self._kwargs["data"]["member_profile"] = {}
    valid = super(AuthUserModelSerializer, self).is_valid(raise_exception=raise_exception)
    return valid

      

+3


source to share


1 answer


Personally, I will write a custom field for profile_image (or extend the image field) and overwrite the to_internal_value method to keep this custom logic. This will be called during field validation. Here's a psuedo example:

class ProfileImageField(ImageField):

    def to_internal_value(self, data):
       converted = ImageHandler().convertImage(data)
       return super(ProfileImageField,self).to_internal_value(converted)

      

To answer your general question, I usually use to_internal_value () methods on fields and serializers to handle any discrepancies between the input and the expected data. These methods are run during validation and allow you to control the data in an obvious way so that someone else will read your code in the future.

Clarification




The serializer itself has a to_interval_value method that allows you to modify / process the data that you pass to it while validating the serializer data (but before the data is validated). Data change at this stage will also occur before the field level check. So, if you want to rename the field that is being passed to your endpoint to what you expect, or if you want to add a null value for a field that was not passed in the data, this is the place to do it.

class MySerializer(serializers.ModelSerializer):

    def to_internal_value(self, data):
       if 'member_profile' not in data:
           data['member_profile'] = {}
       return super(MySerializer,self).to_internal_value(data)

      

+7


source







All Articles