drf 校验与序列化 原样返回

目的

(gender = models.SmallIntegerField(verbose_name='性别', choices=((1, "男"), (2, "女"))))

输入

{
    "name": "szw",
    "gender": 2
}

返回

{
    "id": 2,
    "age": 18,
    "gender":"女"
}

方式一,自定义字段类

自定义字段类

class MyIntegerField(serializers.IntegerField):
    def __init__(self, method_name=None, **kwargs):
        self.method_name = method_name
        super().__init__(**kwargs)
    def bind(self, field_name, parent):
        # The method name defaults to `get_{field_name}`.
        if self.method_name is None:
            #可以自定义方法名
            self.method_name = 'my_get_{field_name}'.format(field_name=field_name)
        super().bind(field_name, parent)
    def get_attribute(self, instance):
        method = getattr(self.parent, self.method_name)
        return method(instance)
    def to_representation(self, value):
        return str(value)

序列化器

class NbInfoSerializer(serializers.ModelSerializer):
    # gender_info = serializers.SerializerMethodField()
    gender = MyIntegerField()
    class Meta:
        model = models.NbUserInfo
        fields = ["id", "name", "age", "gender"]
        extra_kwargs = {
            "id": {"read_only": True},
        }
    def my_get_gender(self, obj):
        return obj.get_gender_display()

view

class NbInfoView(APIView):
    def post(self, request):
        ser = NbInfoSerializer(data=request.data)
        if ser.is_valid():
            instance = ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)

方式二,重写序列化类的to_representation方法(推荐)

封装使用

from collections import OrderedDict
from rest_framework.fields import SkipField
from rest_framework.relations import PKOnlyObject
class NbHookSerializer(object):
    def to_representation(self, instance):
        ret = OrderedDict()
        fields = self._readable_fields
        for field in fields:
            if hasattr(self, 'my_get_%s' % field.field_name):
                value = getattr(self, 'my_get_%s' % field.field_name)(instance)
                ret[field.field_name] = value
            else:
                try:
                    attribute = field.get_attribute(instance)
                except SkipField:
                    continue
                check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
                if check_for_none is None:
                    ret[field.field_name] = None
                else:
                    ret[field.field_name] = field.to_representation(attribute)
        return ret

view

from ext.hook import NbHookSerializer
class SbInfoSerializer(NbHookSerializer, serializers.ModelSerializer):
    class Meta:
        model = models.NbUserInfo
        fields = ["id", "name", "age", "gender"]
        extra_kwargs = {
            "id": {"read_only": True},
        }
    def my_get_gender(self, obj):
        return obj.get_gender_display()
posted @ 2022-10-07 09:27  Sherwin_szw  阅读(48)  评论(0编辑  收藏  举报