drf源码----自定义钩子

点击查看代码
class NBCharField(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 = 'xget_{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 NBModelSerializer(serializers.ModelSerializer):
    gender = NBCharField()

    class Meta:
        model = models.Member
        fields = ['id', 'name', 'age', 'gender', 'depart']
        extra_kwargs = {
            'id': {'read_only': True}
        }

    def xget_gender(self, obj):
        return obj.get_gender_display()

class TestView(APIView):
    authentication_classes = []

    def post(self, request, *args, **kwargs):
        serializer = NBModelSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)
点击查看代码
推荐使用第二种方法
class XXXModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Member
        fields = ['id', 'name', 'age', 'gender', 'depart']
        extra_kwargs = {
            'id': {'read_only': True},
        }

    def to_representation(self, instance):
        ret = OrderedDict()
        fields = self._readable_fields

        for field in fields:
            if hasattr(self, 'nb_%s' % field.field_name):
                value = getattr(self, 'nb_%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

    def nb_gender(self, obj):
        return obj.get_gender_display()

    def nb_depart(self, obj):
        return obj.depart.title
posted @ 2024-03-23 00:23  周亚彪  阅读(10)  评论(0)    收藏  举报