ModelSerializer 类提供了一个快捷方式,可让你基于 Models 自动创建一个 Serializer 类,其中的字段与模型类字段对应。

ModelSerializer 类与常规 Serializer 类相同,不同之处在于:

  • 它会根据模型自动生成一组字段。

  • 它会自动为序列化类生成验证器,例如 unique_together 验证器。

  • 它包含 .create().update() 的简单默认实现。

声明 ModelSerializer 如下所示:

from rest_framework import serializers

class AccountSerializer(serializers.ModelSerializer):
class Meta:
# 指定对哪个模型进行序列化
model = Account
# 指定包含哪些字段
fields = ('id', 'account_name', 'users', 'created')

默认情况下,该类中的所有模型类字段将被映射为相应的序列化类字段。
任何关系(如模型上的外键)都将映射到 PrimaryKeyRelatedField 。除非在序列化关系文档中指定,否则默认不包括反向关系。


检查 ModelSerializer

序列化类能够生成一个表示字符串,可以让你充分检查其字段的状态。在使用 ModelSerializer 进行工作时,这是特别有用的,你需要确定它为你自动创建了哪些字段和验证器。

为此,需要进入 Django shell,然后导入序列化类,实例化它并用 repr() 打印对象表示形式:

>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print(repr(serializer))
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
owner = PrimaryKeyRelatedField(queryset=User.objects.all())

这里会把自动生成的序列化器打印出来。


指定要包含的字段

如果你只希望在模型序列化程序中使用默认字段的子集,则可以使用 fieldsexclude 选项来完成此操作,就像使用 ModelForm 一样。

强烈建议你显式使用 fields 属性序列化的所有字段。这将使你不太可能在模型更改时无意中暴露数据。

比如:

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'users', 'created')

你还可以将 fields 属性设置为特殊值 '__all__',以指示应该使用模型中的所有字段。

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = '__all__'

你可以将 exclude 属性设置为从序列化程序中排除的字段列表。

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
exclude = ('users',)

fieldsexclude 属性中的名称通常映射到模型类的模型字段。

或者 fields 选项中的名称可以映射成属性或方法。而不会变成模型类中的参数。

从版本 3.3.0 开始,必须提供其中一个属性 fieldsexclude


指定嵌套序列化

默认的 ModelSerializer 使用主键进行关联,但你也可以使用 depth 选项轻松生成嵌套表示(自关联)。

为了便于理解,这里我们用上一篇的 User 和 Profile 的关联模型来举例。

# serializers.py

class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('city', 'owner')
depth = 1

现在设定了 depth = 1 ,当我们在 shell 中执行下列操作时:

>>> u = Profile.objects.get(pk=1)
>>> serializer = ProfileSerializer(u)
>>> serializer.data

打印出来的 owner 将不仅仅是对应的 User 的主键,而是包括该 User 的所有字段:

ReturnDict([('city', 'shanghai'),
('owner',
OrderedDict([('id', 1),
('password','xxx'),
('last_login', '2018-05-03T15:08:04.022687Z'),
('is_superuser', True),
('username', 'diego'),
('first_name', ''),
('last_name', ''),
('email', ''),
('is_staff', True),
('is_active', True),
('date_joined', '2018-04-01T15:01:29.451391Z'),
('groups', []),
('user_permissions', [])]))])

默认情况下 depth = 0,这时候序列化的关联对象将只包含该对象的主键:

ReturnDict([('city', 'shanghai'), ('owner', 1)])

显式指定字段

你可以将额外的字段添加到 ModelSerializer,或者通过在类上声明字段来覆盖默认字段,就像你对 Serializer 类所做的那样。

class AccountSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
groups = serializers.PrimaryKeyRelatedField(many=True) class Meta:
model = Account

额外的字段可以对应于模型上的任何属性或可调用的字段。


指定只读字段

你可能希望将多个字段指定为只读。不要显式给每个字段添加 read_only = True 属性,你可以使用快捷方式 Meta 选项 read_only_fields

该选项应该是字段名称的列表或元组,声明如下:

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'users', 'created')
read_only_fields = ('account_name',)

含有 editable = False 的模型字段,AutoField 字段默认设置为只读,并且不需要添加到 read_only_fields 选项。

注意: 有一种特殊情况,只读字段是模型级别的 unique_together 约束的一部分。在这种情况下,序列化类需要验证约束该字段,但也不能由用户编辑。

处理这个问题的正确方法是在序列化类中明确指定字段,同时提供 read_only = True 和 default = ... 关键字参数。

其中一个例子是与当前认证 User 的只读关系,它与另一个标识符是 unique_together 。在这种情况下,你会像这样声明用户字段:

user = serializers.PrimaryKeyRelatedField(
read_only=True,
default=serializers.CurrentUserDefault()
)

其他关键字参数

还有一个快捷方式允许你使用 extra_kwargs 选项在字段上指定任意附加关键字参数。与 read_only_fields 的情况一样,这意味着你不需要在序列化类中显式声明该字段。

该选项是一个字典,将字段名称映射到关键字参数字典。例如:

class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'username', 'password')
extra_kwargs = {'password': {'write_only': True}} def create(self, validated_data):
user = User(
email=validated_data['email'],
username=validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user

作者:SingleDiego
链接:https://www.jianshu.com/p/099d8c688384
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

序列化器:ModelSerializer的更多相关文章

  1. 模型类序列化器ModelSerializer

    定义 比如我们创建一个BookInfoSerializer class BookInfoSerializer(serializers.ModelSerializer): ""&qu ...

  2. DRF 序列化器-Serializer (2)

    作用 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 完成数据校验功能 3. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器 ...

  3. Serializers 序列化组件——ModelSerializer详解

    前面学习Serializers用法时,发现所有的序列化都与我们的模型紧密相关. django_restframework也给我提供了跟模型紧密相关的序列化器——ModelSerializer. 它会根 ...

  4. Django restframework 序列化之 ModelSerializer 小记

    首先介绍一下相关概念 序列化器(Serializer) 1. 自定义型:  继承rest_framework.serializers.Serializer 2. 模型类型:  继承rest_frame ...

  5. DRF框架(三)——media资源路径设置、多表设计复习及补充、序列化组件(ModelSerializer)操作多表(序列化与反序列化)、多表序列化与反序列化整合(重点)

    media资源路径设置  (设置好后把图片放在这个文件夹中,通过链接能访问到图片) 1.先在根目录设置一个media文件夹 2.配置settings.py,加上下面的 MEDIA_URL = '/me ...

  6. 经历了源码的痛苦,掌握DRF的核心序列化器

    目录 DRF的核心--序列化器 序列化器 什么是序列化和反序列化? 序列化 序列化demo 字段类型 字段参数 序列化自定制返回字段 方法一:在序列化类(serializers.py)中写 方法二:在 ...

  7. DRF框架之ModelSerializer序列化器

    ModelSerializer是Serializer的子类,序列化和反序列化跟Serializer一样. ModelSerializer与常规的Serializer相同,但提供了: 基于模型类自动生成 ...

  8. ModelSerializer序列化器实战

    目录 ModelSerializer序列化器实战 单表操作 序列化器类 视图类 路由 模型 多表操作 models.py serializer.py views.py urls.py ModelSer ...

  9. 一: DRF web应用框架基础,及序列化器的使用

    ---恢复内容开始--- 一: web 应用模式(有两种) 1: 前后端不分离(前端从后端直接获取数据) 2: 前后端分离 二: api 接口 原因一: 为了在团队内部形成共识.防止个人习惯差异引起的 ...

随机推荐

  1. Jump Game (Medium)

    主要有两种思路: 一. 本题只需要判断能否到达最后一个数,那么可以采用贪心策略,到达某个位置i后,在直接在这个位置的基础上走nums[i]步,主要保证能一直前进,就能达到终点: 那么,什么时候才不能一 ...

  2. spring:事务的5大隔离级别,7大传播行为

    一.五大隔离级别 ISOLATION_READ_UNCOMMITTED:读未提交 ISOLATION_READ_COMMITTED:读已提交 ISOLATION_REPEATABLE_READ:可重复 ...

  3. [LC] 79. Word Search

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

  4. sqlserver 把两个sql查询语句查询出来的两张表合并成一张表

    第一个sql语句 select companyname gsmc,zb zhibiao from t_gsndzb left join t_companycode on t_gsndzb.gsbh=t ...

  5. Mac系统常用软件

    1.往移动硬盘中拷贝东西.创建文件夹: Mounty 2.解压缩软件(rar): the unarchiver 3.类似Xshell软件: FinalShell(国产) 输入以下命令: curl -o ...

  6. keepalive笔记之二:keepalive+nginx(自定义脚本实现,上述例子也可以实现)

    keepalive的配置文件 ! Configuration File for keepalived global_defs { notification_email { acassen@firewa ...

  7. Spring 错误 cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'context:property-placeholder'.

    我来说下这个出错的原因吧 eclise中xsd的验证问题Description Resource Path Location Type cvc-complex-type.2.4.c: The matc ...

  8. spring-boot-学习笔记(三)-过滤器

      过滤器有两种配置方式,一种是通过注解来完成,一种是通过自定义配置类来设置 这里假设的场景是,定义一个过滤器,过滤所有请求,如果参数中没有username信息则重定向到login_page登录页面, ...

  9. nginx: [emerg] unknown directive “ ” in /usr/local/nginx/conf/vhost/XXX.conf:53报错处理

    开发同事发给我一小段nginx配置,加到服务器上之后,执行nginx -s reload时,出现报错: nginx: [emerg] unknown directive “ ” in /usr/loc ...

  10. TesterHome创始人思寒:如何从手工测试进阶自动化测试?十余年经验分享

      做测试十多年,有不少人问过我下面问题: 现在的手工测试真的不行了吗? 测试工程师,三年多快四年的经验,入门自动化测试需要多久? 自学自动化测试到底需要学哪些东西? 不得不说,随着行业的竞争加剧,互 ...