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. ORs-6-Olfactory Bulb Ratio, ORs Gene Repertoire, and Olfactory Ability

    Olfactory Bulb Ratio, ORs Gene Repertoire, and Olfactory Ability 1.Olfactory Bulb的生物学意义:a.生存 b.嗅觉能力 ...

  2. nowcoder-548C-Tachibana Kanade Loves Review

    链接:https://ac.nowcoder.com/acm/contest/548/C来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言10485 ...

  3. 线程同步Lock锁

    Lock接口历史 java1.5版本之前只有synchronized一种锁,lock是java1.5版本之后提供的接口.lock接口与synchronized接口功能相同,但是需要手动获取锁和释放锁. ...

  4. Doc: NetBeans

    NetBeans的最新版本已经更新为Apache NetBeans. 安装JDK 在Mac OS X下,有".dmg"的安装包,可以直接安装.只要JDK的版本大于1.8.0就可以安 ...

  5. 7)加了基础控制器Controller.php

    文件目录展示: 改动代码展示: Controller.php <?php /** * Created by PhpStorm. * User: Interact * Date: 2017/8/2 ...

  6. jtemplates使用+同内容列合并

    function ImportStatistics(val, pros) { top.$.jBox.tip("导入已完成,正在统计整理导入的数据...", 'loading'); ...

  7. spring学习笔记二:spring使用构造方法注入(set方式注入)

    项目目录树: 1.spring的依赖包配置 * SPRING_HOME/dist/spring.jar * SPRING_HOME/lib/log4j/log4j-1.2.14.jar * SPRIN ...

  8. [洛谷P3366] [模板] 最小生成树

    存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...

  9. SWUST OJ 青蛙的约会之二(0481)

    青蛙的约会之二(0481) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 138 Accepted: 28   Descriptio ...

  10. HBase完全分布式集群搭建

    HBase完全分布式集群搭建 hbase和hadoop一样也分为单机版,伪分布式版和完全分布式集群版,此文介绍如何搭建完全分布式集群环境搭建.hbase依赖于hadoop环境,搭建habase之前首先 ...