1、ModelSerializer序列化
一、定义ModelSerializer序列化器html
from rest_framework import serializers
from .models import Book, Publisher前端
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 与Book表对应python
# 这三种状况不能同时使用 # 1.取所有字段 fields = "__all__" # 2.自定义包含字段 # fields = ["id", "title", "pub_time"] # 输出:[{"id": 1, "title": "python开发", "pub_time": "2011-08-27"},...] # 3.排除某些字段 # exclude = ["id", "category","author", "publisher"] # 输出:[{"title": "python开发", "pub_time": "2011-08-27"},...]
须要注意的是:取所有字段、取自定义字段、排除某些字段这三种筛选不能同时使用。django
二、外键关系的序列化
注意:当序列化类META定义了depth时,这个序列化类中引用字段(外键)则自动变为只读。api
depth 表明找嵌套关系的第几层。ide
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 与Book表对应
fields = "all"
depth = 1
添加depth前,显示效果:post
添加depth后,显示效果:ui
由上图可知,只会查看嵌套深度一层的内容。设计
三、自定义字段
不少字段默认显示的是选择的key值,但要给用户展现的是value值。rest
所以能够声明一些字段来覆盖默认字段来进行自定制。
class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到对应中文
class Meta: model = Book # 与Book表对应 fields = "__all__"
显示效果以下所示:
四、Meta中其余关键字参数
官方文档地址:https://www.django-rest-framework.org/api-guide/serializers/
(1)指定只读字段
但愿将多个字段指定为只读。推荐使用快捷的Meta选项read_only_fields,而不是显式地使用read_only=True属性添加每一个字段。示例以下所示:
class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)
class Meta: model = Book fields = "__all__" depth = 1 read_only_fields = ["id"]
模型字段有设置 editable=False, AutoField 字段默认设置为只读,不须要添加到 read_only_fields 选项。
(2)给字段添加额外参数——extra_kwargs
使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数---字典格式。
class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)
class Meta: model = Book fields = "__all__" depth = 1 read_only_fields = ["id"] extra_kwargs = {"title": {"validators": [my_validate,]}}
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'username', 'password']
extra_kwargs = {'password': {'write_only': True}}
若是字段已在序列化程序类中显式声明,则该extra_kwargs选项将被忽略。
五、post和patch请求
因为depth会让外键变成只读,因此定义一个序列化的类,其实只要去掉depth就能够了。
class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)
class Meta: model = Book fields = "__all__" # fields = ["id", "title", "pub_time"] # exclude = ["user"] # 分别是全部字段 包含某些字段 排除某些字段 read_only_fields = ["id"] extra_kwargs = {"title": {"validators": [my_validate,]}}
六、SerializerMethodField
外键关联的对象有不少字段是用不到的,都传给前端会有数据冗余。须要本身去定制序列化外键对象的那些字段。
from rest_framework import serializers
from .models import Book, Publisher
class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到对应中文
class Meta: model = Book # 与Book表对应 fields = "__all__"
查看页面 http://127.0.0.1:8000/books/list,显示效果以下所示:
添加 SerializerMethodField的使用,获取显示外联字段:
class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到对应中文
# SerializerMethodField的使用,获取显示外联字段 publisher = serializers.SerializerMethodField() author= serializers.SerializerMethodField() def get_author(self, obj): authors_query_set = obj.author.all() # 拿到全部做者信息 return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set] # 列表推导式 def get_publisher(self, obj): # obj是咱们序列化的每一个Book对象 publisher_obj = obj.publisher # 正向查询 return {'id': publisher_obj.id} class Meta: model = Book # 与Book表对应 fields = "__all__"
显示效果以下所示:
2、ModelSerializer反序列化
一、ModelSerializer原生POST请求
再将 SerDemo/serializers.py 下 BookSerializer 恢复为原生状态:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 与Book表对应
fields = "all"
不用自定义create方法,可直接提交提交post请求以下:
数据新增成功,以下所示:
二、SerializerMethodField改写
class BookSerializer(serializers.ModelSerializer):
# SerializerMethodField的使用,获取显示外联字段
category_display = serializers.SerializerMethodField(read_only=True) # 从新定义,避免重写,影响反序列化
publisher_info = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)
def get_category_display(self, obj): return obj.get_category_display() # ORM方法获取中文 def get_authors(self, obj): authors_query_set = obj.author.all() # 拿到全部做者信息 return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set] # 列表推导式 def get_publisher_info(self, obj): # obj是咱们序列化的每一个Book对象 publisher_obj = obj.publisher # 正向查询 return {'id': publisher_obj.id} class Meta: model = Book # 与Book表对应 fields = "__all__"
显示效果以下所示:
能够从上图看到,除了显示了category_display、authors、publisher_info,也显示了category、publisher、author。
三、extra_kwargs配置字段参数
class BookSerializer(serializers.ModelSerializer):
# SerializerMethodField的使用,获取显示外联字段
category_display = serializers.SerializerMethodField(read_only=True) # 从新定义,避免重写,影响反序列化
publisher_info = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)
def get_category_display(self, obj): return obj.get_category_display() # ORM方法获取中文 def get_authors(self, obj): authors_query_set = obj.author.all() # 拿到全部做者信息 return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set] # 列表推导式 def get_publisher_info(self, obj): # obj是咱们序列化的每一个Book对象 publisher_obj = obj.publisher # 正向查询 return {'id': publisher_obj.id} class Meta: model = Book # 与Book表对应 fields = "__all__" extra_kwargs = { "category": {"write_only": True}, # 避免直接改写 "publisher": {"write_only": True}, "author": {"write_only": True} }
如此就再也不显示category、publisher、author了,显示效果以下所示:
3、Serializer与ModelSerializer区别
本文转载于https://www.cnblogs.com/xiugeng/p/11460855.html