Django REST Framework 自定义字段与序列化器高级用法二

from collections import OrderedDict
from rest_framework.fields import SkipField
from rest_framework.relations import PKOnlyObject


class hookSerializer(object):
    def to_representation(self, instance):
        ret = OrderedDict()  # 保持字段顺序
        fields = self._readable_fields  # 获取可读字段列表
        for field in fields:
            # 检查是否存在hk_前缀的钩子方法
            if hasattr(self, 'hk_%s' % field.field_name):
                value = getattr(self, 'hk_%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
from api.ext.hook import hookSerializer
class CreateSerializer(hookSerializer, serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = ["id", "username", "age", "gender", "depart"]
        extra_kwargs = {
            "id": {"read_only": True},
            "age": {"write_only": True}  # 不会出现在输出中
        }

    # 性别字段钩子
    def hk_gender(self, obj):
        return obj.get_gender_display()  # 获取choice字段的显示值
// 输入(POST)
{"username":"李光旭","age":23,"gender":1,"depart":2}

// 输出(GET)
{
  "id": 19,
  "username": "李光旭",
  "gender": "男",  // 经过hk_gender转换
  "depart": 2
}
posted @ 2025-07-29 15:01  咩啊咩咩咩  阅读(16)  评论(0)    收藏  举报