不同于Serializer
,可以帮助我们完成。
- 它将根据模型自动生成一组字段。
- 它将根据模型上的参数自动生成序列化程序的验证程序。
- 它包括
create() 和 update()
简单默认实现。
from rest_framework import serializers
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
# exclude = ('created', )
# read_only_fields = ('email', ) 指定只读字段
# extra_kwargs = {'created': {'write_only': True}}
Meta属性
指定字段—fields
-
__all__
指模型下所有字段 - 元组或者列表指定字段
指定字段—exclude
和fields正好相反,指不需要一些字段。字段比较多它可能比较好用。
注意
:无论是feilds or exclude
被过滤的的字段都不能序列化或者反序列化。
指定只读字段
指定字段只做序列化,不做反序列化。功能等同字段参数read_only=True
。默认就被设置为只读的不需要。
附加关键词
还可以通过使用extra_kwargs选项快捷地在字段上指定任意附加的关键字参数。在read_only_fields这种情况下,你不需要在序列化器上式的声明该字段。
Serializer
其实,在日常使用过程中。ModelSerializer
比较常用,很多继承自Serializer
被使用。
to_representation
重写这个选项作为序列化读取。使用ModeSerializer
时为了适应反序列化。如:关联外键
and choices类型
and 额外附加字段
等。
class CommentSerializer(BaseSerializer):
def to_representation(self, data):
ret = super().to_representation(data)
if ret:
# 逻辑
ret['a'] = 'hello'
pass
return ret
create
通过验证数据将被保存
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:
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)
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.
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)
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
update
数据将被更新
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 potentially 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
create
和update
将共用验证器
。所以在使用序列化器时应该考虑更加全面。序列化器默认是保存和更新是根据序列化后得到的字段。如果只是操作部分字段使用Serializer(partial=True)
默认为False。