前面学习Serializers用法时,发现所有的序列化都与我们的模型紧密相关。

  django_restframework也给我提供了跟模型紧密相关的序列化器——ModelSerializer。

  它会根据模型自动生成一组字段;它简单的默认实现了.update()以及.create()方法。

一、ModelSerializer序列化

1、定义ModelSerializer序列化器

# 针对models设计和声明序列化类
from rest_framework import serializers
from .models import Book, Publisher class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 与Book表对应 # 这三种情况不能同时使用
# 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"},...]

  需要注意的是:取全部字段、取自定义字段、排除某些字段这三种筛选不能同时使用。

2、外键关系的序列化

  注意:当序列化类META定义了depth时,这个序列化类中引用字段(外键)则自动变为只读。

  depth 代表找嵌套关系的第几层。

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 与Book表对应
fields = "__all__"
depth = 1

  添加depth前,显示效果:

  

  添加depth后,显示效果:

  

  由上图可知,只会查看嵌套深度一层的内容。

3、自定义字段

  很多字段默认显示的是选择的key值,但要给用户展示的是value值。

  因此可以声明一些字段来覆盖默认字段来进行自定制。

class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到对应中文 class Meta:
model = Book # 与Book表对应
fields = "__all__"

  显示效果如下所示:

  

4、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选项将被忽略。

5、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,]}}

6、SerializerMethodField

  外键关联的对象有很多字段是用不到的,都传给前端会有数据冗余。需要自己去定制序列化外键对象的那些字段。

# 针对models设计和声明序列化类
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__"

  显示效果如下所示:

  

二、ModelSerializer反序列化

1、ModelSerializer原生POST请求  

  再将 SerDemo/serializers.py 下 BookSerializer 恢复为原生状态:

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 与Book表对应
fields = "__all__"

  不用自定义create方法,可直接提交提交post请求如下:

  

  数据新增成功,如下所示:

  

2、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。

3、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了,显示效果如下所示:

  

三、Serializer与ModelSerializer区别

  

最新文章

  1. 编写高质量代码:改善Java程序的151个建议(第5章:数组和集合___建议75~78)
  2. iOS之判断字符串是否为空字符的方法
  3. 软件测试第四周--关于int.parse()的类型转换问题
  4. Vuejs使用笔记 --- component内部实现
  5. nginx 与 lua 开发环境搭建
  6. 用shell脚本批量修改文件后缀名
  7. XAML中的Path
  8. Clock network
  9. 查看和清除本机DNS缓存记录
  10. Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Truncated incorrect DOUBLE value: 'L
  11. 分享13道上海尚学堂拿回来的Java面试真题,这些都是Java核心常见问题,想拿OFFER必看!
  12. Eclipse中设置Java代码格式化
  13. python -- 约束、异常处理、MD5
  14. hdu 1394 Minimum Inversion Number - 树状数组
  15. C# 连接PDA扫码枪
  16. fedora如何删除某个包且不删除依赖它的相关包
  17. Spring中使用StandardServletMultipartResolver进行文件上传
  18. Warm up HDU - 4612( 树的直径 边双连通分量)
  19. CMD命令下访问Oracle数据库
  20. Haskell语言学习笔记(38)Lens(1)

热门文章

  1. fis3打包中的一些注意事项
  2. Spring Cloud 教程
  3. python调用C++实例:用C++对numpy执行BFS(广度优先搜索)
  4. 在 ASP.NET Core 项目中使用 npm 管理你的前端组件包
  5. zabbix--完整安装攻略
  6. MySQL中使用group_concat遇到的坑
  7. 实例演示 C# 中 Dictionary<Key, Value> 的检索速度远远大于 hobbyList.Where(c => c.UserId == user.Id)
  8. oracle trunc 日期 数字 的使用例子
  9. FtpClient上传文件速度非常慢,而且大小为0,上传失败
  10. sqlite3数据库最大可以是多大?可以存放多少数据?读写性能怎么样?