重写Django-Rest-Framework序列化器的is_valid方法

5
我有一个关于重写is_valid的问题。Self是一个rest_framework.serializers.ModelSerializer。我试图找出是否有一种更好的方式来修改内部数据,而不是读/写data._kwargs属性。我知道我可以通过调用self.get_initial()获取经过预验证的数据。但我也想能够编写数据。这里的目的是将未正确格式化的图像数据转换为模型可接受的格式,以使我们的API更加灵活。我知道还可能有其他实现我的目标的方法,但我的一般性问题是:

在调用is_valid()之前有没有一种很好的方法来设置序列化器上的数据?

因为它适用于其他情况。谢谢!
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
1个回答

10

就我个人而言,我会为"profile_image"编写一个自定义字段(或者扩展图像字段),并重写to_internal_value方法以包含此自定义逻辑。这将在字段验证期间被调用。以下是一个伪代码示例:

class ProfileImageField(ImageField):

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

回答你的一般性问题,我通常使用自定义 to_internal_value() 方法来处理字段和序列化程序之间的任何差异。这些方法在验证期间运行,并允许您以明显的方式控制数据,方便未来读取您代码的人。

澄清


序列化程序本身具有 'to_internal_value' 方法,它允许您在序列化程序数据验证期间(但在数据本身验证之前)修改/处理传递给它的数据。此时修改数据也将发生在字段级别验证之前。因此,如果您想将传递到您端点的字段重命名为您期望的名称,或者如果您想为未在数据中传递的字段添加空值,则应在此处执行该操作。

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)

1
谢谢,我可能会转换到你的方法。然而,我仍然有一个问题,是否有一种好的方法可以在调用is_valid()之前更改序列化器对象(在对象本身上)上的数据? - Diesel
1
我添加了一个澄清,我相信这更好地回答了你的问题。 - Mark Galloway
这对我来说不起作用,因为可变标志,直到我从此链接 https://dev59.com/lVcP5IYBdhLWcg3wN3mP#51196932 进行了更改。 - alexbhandari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接