点击查看代码
class Field:
_creation_counter = 0
def __init__(self):
self._creation_counter = Field._creation_counter
Field._creation_counter += 1
class IntegerField(Field):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def to_representation(self, value):
return int(value)
class CharField(Field):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def to_representation(self, value):
return str(value)
id = serializers.IntegerField()
title = serializers.CharField()
order = serializers.IntegerField()
点击查看代码
class Field:
def get_attribute(self, instance):
return get_attribute(instance, self.source_attrs)
class SerializerMetaclass(type):
@classmethod
def _get_declared_fields(cls, bases, attrs):
fields = [(field_name, attrs.pop(field_name))
for field_name, obj in list(attrs.items())
if isinstance(obj, Field)]
fields.sort(key=lambda x: x[1]._creation_counter)
known = set(attrs)
def visit(name):
known.add(name)
return name
base_fields = [
(visit(name), f)
for base in bases if hasattr(base, '_declared_fields')
for name, f in base._declared_fields.items() if name not in known
]
return OrderedDict(base_fields + fields)
def __new__(cls, name, bases, attrs):
attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
return super().__new__(cls, name, bases, attrs)
class BaseSerializer(Field):
def __init__(self, instance=None, data=empty, **kwargs):
self.instance = instance
if data is not empty:
self.initial_data = data
self.partial = kwargs.pop('partial', False)
self._context = kwargs.pop('context', {})
kwargs.pop('many', None)
super().__init__(**kwargs)
def __new__(cls, *args, **kwargs):
if kwargs.pop('many', False):
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)
@classmethod
def many_init(cls, *args, **kwargs):
child_serializer = cls(*args, **kwargs)
list_kwargs = {
'child': child_serializer,
}
meta = getattr(cls, 'Meta', None)
list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
return list_serializer_class(*args, **list_kwargs)
@property
def data(self):
if not hasattr(self, '_data'):
if self.instance is not None and not getattr(self, '_errors', None):
self._data = self.to_representation(self.instance)
elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
self._data = self.to_representation(self.validated_data)
else:
self._data = self.get_initial()
return self._data
class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
@property
def data(self):
ret = super().data
return ReturnDict(ret, serializer=self)
def to_representation(self, instance):
ret = OrderedDict()
fields = self._readable_fields
for field in fields:
attribute = field.get_attribute(instance)
ret[field.field_name] = field.to_representation(attribute)
return ret
@property
def _readable_fields(self):
for field in self.fields.values():
if not field.write_only:
yield field
@cached_property
def fields(self):
fields = BindingDict(self)
for key, value in self.get_fields().items():
fields[key] = value
return fields
class ModelSerializer(Serializer):
def get_fields(self):
if self.url_field_name is None:
self.url_field_name = api_settings.URL_FIELD_NAME
assert hasattr(self, 'Meta'), (
'Class {serializer_class} missing "Meta" attribute'.format(
serializer_class=self.__class__.__name__
)
)
assert hasattr(self.Meta, 'model'), (
'Class {serializer_class} missing "Meta.model" attribute'.format(
serializer_class=self.__class__.__name__
)
)
if model_meta.is_abstract_model(self.Meta.model):
raise ValueError(
'Cannot use ModelSerializer with Abstract Models.'
)
declared_fields = copy.deepcopy(self._declared_fields)
model = getattr(self.Meta, 'model')
depth = getattr(self.Meta, 'depth', 0)
if depth is not None:
assert depth >= 0, "'depth' may not be negative."
assert depth <= 10, "'depth' may not be greater than 10."
info = model_meta.get_field_info(model)
field_names = self.get_field_names(declared_fields, info)
extra_kwargs = self.get_extra_kwargs()
extra_kwargs, hidden_fields = self.get_uniqueness_extra_kwargs(
field_names, declared_fields, extra_kwargs
)
fields = OrderedDict()
for field_name in field_names:
if field_name in declared_fields:
fields[field_name] = declared_fields[field_name]
continue
extra_field_kwargs = extra_kwargs.get(field_name, {})
source = extra_field_kwargs.get('source', '*')
if source == '*':
source = field_name
field_class, field_kwargs = self.build_field(
source, info, model, depth
)
field_kwargs = self.include_extra_kwargs(
field_kwargs, extra_field_kwargs
)
fields[field_name] = field_class(**field_kwargs)
fields.update(hidden_fields)
return fields
点击查看代码
class TestSerializer(serializers.ModelSerializer):
id = 123
age = serializers.IntegerField(source='age')
gender = serializers.CharField(source='get_gender_display')
depart = serializers.CharField(source='depart.title')
datetime = serializers.DateTimeField(format='%Y-%m-%d')
class Meta:
model = models.Member
fields = ['name', 'age', 'gender', 'depart', 'datetime']
TestSerializer._declared_fields
queryset = models.Member.objects.all()
ser = TestSerializer(instance=queryset,many=True)
instance = models.Member.objects.all().first()
ser = TestSerializer(instance=instance, many=False)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本