class BaseSerializer(Field)
"""
The BaseSerializer class provides a minimal class which may be used
for writing custom serializer implementations.
这个类提供一个最小化的类,可以用来写自定义的序列化实现
Note that we strongly restrict the ordering of operations/properties
that may be used on the serializer in order to enforce correct usage.
序列化上会用到的操作/属性的顺序是被限制的,为了正确的使用
In particular, if a `data=` argument is passed then:
如果传递data=这个参数
.is_valid() - Available.可用
.initial_data - Available.可用
.validated_data - Only available after calling `is_valid()`调用is_valid之后可用
.errors - Only available after calling `is_valid()`
.data - Only available after calling `is_valid()`
If a `data=` argument is not passed then:
一般来水不会传递data这个参数
.is_valid() - Not available.
.initial_data - Not available.
.validated_data - Not available.
.errors - Not available.
.data - Available.
"""
def __init__(self, instance=None, data=empty, **kwargs): #初始化,传入instance参数(一个model class的实例)
self.instance = instance #instance给到self
if data is not empty:
self.initial_data = data
self.partial = kwargs.pop('partial', False) #将额外的字典参数中,partial,context给到self,如果没有,给出默认值
self._context = kwargs.pop('context', {})
kwargs.pop('many', None) #将many这个key删除
super().__init__(**kwargs) #继承父类的其余属性
# 对self.data属性函数化,为了加判断
# 将instance转化为data
@property
def data(self):
if hasattr(self, 'initial_data') and not hasattr(self, '_validated_data'):
msg = (
'When a serializer is passed a `data` keyword argument you '
'must call `.is_valid()` before attempting to access the '
'serialized `.data` representation.\n'
'You should either call `.is_valid()` first, '
'or access `.initial_data` instead.'
)
raise AssertionError(msg)
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):
# 继承父类的data属性,然后调用ReturnDict函数返回
@property
def data(self):
ret = super().data
return ReturnDict(ret, serializer=self)
app目录
serializer.py
# 创建serializers.Serializer的子类
# 几个field是Fields.py里Field的几个子类
class ColorsSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
colors = serializers.CharField(max_length=10)
def create(self, validated_data):
return Colors.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.colors = validated_data.get('colors', instance.colors)
instance.save()
return instance
views.py
def test(request):
color = Colors(id=2,colors='red') #color为一个xxx.models.Colors的instance
print(color) #一个instance,由该model类的__str__(self)的返回值决定
serializer = ColorsSerializer(instance=color) #将这个instance传入序列化类,返回一个序列化实例
print(serializer.data) #
print(type(serializer.data)) # {'id': 2, 'colors': 'red'}
return HttpResponse('done')
class ModelSerializer(Serializer):
"""
A `ModelSerializer` is just a regular `Serializer`, except that:
* A set of default fields are automatically populated.
* A set of default validators are automatically populated.
* Default `.create()` and `.update()` implementations are provided.
*将自动填充一组默认字段。
*将自动填充一组默认验证器。
*提供了默认的`.create()`和`.update()`实现。elds
The process of automatically determining a set of serializer fields
based on the model fields is reasonably complex, but you almost certainly
don't need to dig into the implementation.
If the `ModelSerializer` class *doesn't* generate the set of fields that
you need you should either declare the extra/differing fields explicitly on
the serializer class, or simply use a `Serializer` class.
如果“modelserializer”class没有生成所需字段,我应该在序列化类明确申明额外字段
或者直接使用Serializer类
"""
# Default `create` and `update` behavior...
def create(self, validated_data):
"""
We have a bit of extra checking around this in order to provide
descriptive messages when something goes wrong, but this method is
essentially just:
我们在这里有一些额外的检查,为了当发生错误时可以提供一些可描述的信息。
但这个方法,本质上就是:
return ExampleModel.objects.create(**validated_data)
If there are many to many fields present on the instance then they
cannot be set until the model is instantiated, in which case the
implementation is like so:
如果实例中有多对对字段,需要以下实现:先把字段从validated_data pop出来,
example_relationship = validated_data.pop('example_relationship')
instance = ExampleModel.objects.create(**validated_data)
instance.example_relationship = example_relationship
return instance
The default implementation also does not handle nested relationships.
If you want to support writable nested relationships you'll need
to write an explicit `.create()` method.
"""
raise_errors_on_nested_writes('create', self, validated_data)
# 在Meta嵌套类中的model属性
ModelClass = self.Meta.model
# Remove many-to-many relationships from validated_data.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
# 把model类的字段信息给到info
# 处理多对多字段
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_data):
many_to_many[field_name] = validated_data.pop(field_name)
# 表插入,返回到instance
try:
instance = ModelClass._default_manager.create(**validated_data)
except TypeError:
tb = traceback.format_exc()
msg = (
'Got a `TypeError` when calling `%s.%s.create()`. '
'This may be because you have a writable field on the '
'serializer class that is not a valid argument to '
'`%s.%s.create()`. You may need to make the field '
'read-only, or override the %s.create() method to handle '
'this correctly.\nOriginal exception was:\n %s' %
(
ModelClass.__name__,
ModelClass._default_manager.name,
ModelClass.__name__,
ModelClass._default_manager.name,
self.__class__.__name__,
tb
)
)
raise TypeError(msg)
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
field = getattr(instance, field_name)
field.set(value)
return instance
# 在instance上设定每个属性,然后save
def update(self, instance, validated_data):
raise_errors_on_nested_writes('update', self, validated_data)
info = model_meta.get_field_info(instance)
# Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
m2m_fields = []
for attr, value in validated_data.items():
if attr in info.relations and info.relations[attr].to_many:
m2m_fields.append((attr, value))
else:
setattr(instance, attr, value)
instance.save()
# Note that many-to-many fields are set after updating instance.
# Setting m2m fields triggers signals which could potentialy change
# updated instance and we do not want it to collide with .update()
for attr, value in m2m_fields:
field = getattr(instance, attr)
field.set(value)
return instance
# Determine the fields to apply...
app目录
serializers.py
class ColorsSerializer(serializers.ModelSerializer):
class Meta:
model = Colors
fields = ('url', 'id', 'colors')
views.py
def test(request):
color = Colors(id=2,colors='red')
print(color)
serializer = ColorsSerializer(instance=color,context={'request': request})
print(serializer.data)
print(type(serializer.data))
return HttpResponse('done')
几种多表操作的field应用
读取外键的某个字段
# Clothes的color是外键,默认情况下,color字段会对应母表的主键,id。
# 使用SlugRelatedField可以指向外键,slug_field表示获取哪个字段返回给color
# 这里color这个属性就被重写了
class ClothesSerializer(serializers.ModelSerializer):
color = serializers.SlugRelatedField(queryset=Colors.objects.all(), slug_field='colors_cn')
class Meta:
model = Clothes
fields = ('url', 'id', 'color', 'desc')