#Django分离序列化器配置
##统一的返回数据类
设置code,message,data,和一些外添加的信息
class ResAPI:
def __init__(self):
self.code = 200 # 默认成功状态码
self.message = 'Success' # 默认成功消息
self.data = "" # 默认数据为空
self.extra = {} # 额外信息字段,可以根据需要扩展
def set_code(self, code):
"""设置响应的状态码"""
self.code = code
def set_message(self, message):
"""设置响应的消息"""
self.message = message
def set_data(self, data):
"""设置响应的数据"""
self.data = data
def add_extra(self, key, value):
"""添加额外信息到响应中"""
self.extra[key] = value
def set_error(self,data):
self.code = 0
self.message = data
def to_response(self):
"""将当前对象的状态转换为JsonResponse"""
response_dict = {
'code': self.code,
'message': self.message,
'data': self.data,
**self.extra # 展开额外信息到响应字典中
}
return response_dict
##对序列化器返回结果的重写
class CustomModelSerializer(ModelSerializer):
def is_valid(self, *, raise_exception=False):
try:
super().is_valid(raise_exception=raise_exception)
except ValidationError as e:
resapi = ResAPI()
resapi.set_code(e.status_code)
for k,v in e.detail.items():
resapi.set_message(f"{k}-{v[0]}")
resapi.add_extra(k,v[0])
raise ValidationError(resapi.to_response()) # 重写验证失败数据返回
# 添加自定义的钩子函数,用于序列化输出 deal_{field_name}(self,instance)
def to_representation(self, instance):
"""
Object instance -> Dict of primitive datatypes.
"""
ret = {}
fields = self._readable_fields
for field in fields:
field_name = field.field_name
deal_method_name = f'deal_{field_name}'
# 检查是否存在 deal_ 方法
if hasattr(self, deal_method_name):
deal_method = getattr(self, deal_method_name)
try:
# 调用 deal_ 方法并获取结果
attribute = deal_method(instance)
except SkipField:
continue
ret[field.field_name] = attribute
else:
try:
attribute = field.get_attribute(instance)
except SkipField:
continue
# We skip `to_representation` for `None` values so that fields do
# not have to explicitly deal with that case.
#
# For related fields with `use_pk_only_optimization` we need to
# resolve the pk value.
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
##自定义字段
绑定获取数据函数,执行函数获取返回结果
class NbChartField(CharField):
def __init__(self,method_name=None,**kwargs):
self.method_name = method_name
super().__init__(**kwargs)
def bind(self, field_name, parent):
if self.method_name is None:
self.method_name = f"cget_{field_name}"
super().bind(field_name, parent)
def to_representation(self, value):
method = getattr(self.parent,self.method_name,None)
return method(value)