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
}