简介

初次见到serializers文件,想必大家都会感到陌生,所以,我们不妨换个词来形容他的作用,那就是django 中的Form,这样是不是感觉熟悉了一点。

实际上,serializers 的作用和Form也差不多,可以帮我们验证提交的表单,和取出model里面的字段

fields

既然是序列化数据,那么我们需要指定对应的一些字段,serializers中的字段和model中的类似,有BooleanField,CharField,IntegerField等,不同地方在于model中有ForeignKey,在serializers中没有,对于这一部分,我们可以使用SerializerMethodField来处理(文章后面会介绍)。

例如

# 举例子
mobile = serializers.CharField(max_length=11, min_length=11)
age = serializers.IntegerField(min_value=1, max_value=100)
# format可以设置时间的格式,下面例子会输出如:2018-1-24 12:10
pay_time = serializers.DateTimeField(read_only=True,format='%Y-%m-%d %H:%M')
recv_people = serializers.DictField(read_only=True, source='recv_people_info')
settlementinvoicemodel = SettlementInvoiceSerializers(read_only=True, many=False, required=False)
nego = serializers.DictField(read_only=True, source='nego_info')
  • 常用通用参数

read_only 只在输出时显示,提交数据的时候,跳过

write_only 同read_only 相反,只在提交数据时用

source 获取本字段的方法,会调用model 中对应的方法,我们可以自己定义相关的实现

label 字段的显示,方便api页面文档的显示

help_text 提示文字,方便api页面文档的显示

ModelSerializer

既然在model中,我们有定义了字段的类型信息等,而这一部分和serializer中的类似,所以我们就想能不能简化这部分操作,不用按照model中的字段一个一个添加。正好ModelSerializer帮我们解决了这种问题,我们只需要对model中的字段做选择要哪些,或者不要哪些就行了。

# 获取Permission model 中除status以外的字段, 并且user 为只读
class PermissionSerializers(serializers.ModelSerializer):
class Meta:
model = Permission
read_only_fields = ("user",) # 定义read_only_fields
exclude = ("status",)
  • 处理save的流程

    流程如下图所示

    我们先简单看下viewset中的create mixin和update mixin源码,如下

    class CreateModelMixin(object):
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True) # 必须先调用is_valid 验证才能调用save
    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)
    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def perform_create(self, serializer):
    serializer.save() class UpdateModelMixin(object):
    """
    Update a model instance.
    """
    def update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
    serializer.is_valid(raise_exception=True)
    self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None):
    instance._prefetched_objects_cache = {} return Response(serializer.data) def perform_update(self, serializer):
    serializer.save()

    其中用到了get_serializer方法,和serializer相关,所以也贴出这部分的源码

    def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)

    在create,update中都用到了serializer.save()方法,我们在来看看save中做了什么操作

    def save(self, **kwargs):
    # 去掉了assert 出来的错误信息
    assert not hasattr(self, 'save_object')
    assert hasattr(self, '_errors')
    assert not self.errors
    assert 'commit' not in kwargs
    assert not hasattr(self, '_data') validated_data = dict(
    list(self.validated_data.items()) +
    list(kwargs.items())
    ) # 根据传入的instance 对象 判断是create 还是update
    if self.instance is not None:
    self.instance = self.update(self.instance, validated_data)
    assert self.instance is not None
    else:
    self.instance = self.create(validated_data)
    assert self.instance is not None
    return self.instance

    可以看出,最终的create,update方法到了我们自己定义的serialiers的create, update 方法,在有额外的需求的时候,我们经常在这里修改。

  • validate

    ModelSerializer 已经自带了根据model中的字段来验证数据,可很多时候,我们需要额外的认为加一些判断,此时,我么可以自己写serializers.validate方法,如下,

     def validate(self, data):
    cellphone = data.get('cellphone', '')
    phone_rst = PHONE_REG.search(str(cellphone)) # 对电话啊号码做正则验证
    if phone_rst is not None:
    phone = phone_rst.group(0)
    else:
    phone = ''
    assert cellphone == phone, '手机号格式错误'
    data['cellphone'] = cellphone
    return data
  • 序列化数据

    前面讲了post,update model, 接下来,我们来看看怎么使用serializer序列话我们的输出。一般的,我们是基于model中的字段进行开发,这部分数据不需要单独处理。可问题是,在开发过程中,经常会增加一些其他的字段来返回,所以我们来看看serializer中增加其他字段数据的方法。

    第一种方式 是使用 source 参数, 前面介绍字段的时候说过了。还有一种就是使用SerializerMethodField 字段,使用方法如下

    items = serializers.SerializerMethodField()
    # 定义items的获取
    def get_items(self, obj):
    qs = obj.profile_set.filter(status=True)
    serializer = ProFileSerializers(qs, many=True) # 从另一个serializer获取数据
    ret = serializer.data
    return ret
  • 外键的序列化

    可以将写好的serializers 直接挪过来,像下面这样

    class SeSerializers(serializers.ModelSerializer):
    cat = CatSerializers(read_only=True, many=True)

实际的使用中,个人感觉还是使用SerializerMethodField 字段更为方便,清晰。

Django-rest-framework(二)serializers 使用的更多相关文章

  1. Django Rest Framework(二)

    •基于Django 先创建一个django项目,在项目中创建一些表,用来测试rest framework的各种组件 models.py class UserInfo(models.Model): &q ...

  2. Django REST framework+Vue 打造生鲜超市(十二)

    十三.首页.商品数量.缓存和限速功能开发  13.1.轮播图接口实现 首先把pycharm环境改成本地的,vue中local_host也改成本地 (1)goods/serializer class B ...

  3. django rest framework serializers

    django rest framework serializers序列化   serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用:- 将qu ...

  4. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  5. Django Rest Framework源码剖析(六)-----序列化(serializers)

    一.简介 django rest framework 中的序列化组件,可以说是其核心组件,也是我们平时使用最多的组件,它不仅仅有序列化功能,更提供了数据验证的功能(与django中的form类似). ...

  6. Django REST framework+Vue 打造生鲜电商项目(笔记二)

    (转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...

  7. Django Rest Framework源码剖析(二)-----权限

    一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...

  8. Sentry 开发者贡献指南 - Django Rest Framework(Serializers)

    Serializer 用于获取复杂的 python 模型并将它们转换为 json.序列化程序还可用于在验证传入数据后将 json 反序列化回 Python 模型. 在 Sentry,我们有两种不同类型 ...

  9. DRF Django REST framework 之 解析器(二)

    引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...

  10. Django REST framework+Vue 打造生鲜超市(四)

    五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...

随机推荐

  1. 修改K3数据是简介方法

    如  及时库存里有个别产品库存没有库位  是*号的 这个时候  我们创建一个其他出库单,把这个没有库位的产品输入进去,库位随便写个 如002 保存,审核不了的  会提示负库存 去后台找到此单据号 修改 ...

  2. [转]谷歌Chrome浏览器开发者工具教程—基础功能篇

    来源:http://www.xiazaiba.com/jiaocheng/5557.html Chrome(F12开发者工具)是非常实用的开发辅助工具,对于前端开发者简直就是神器,但苦于开发者工具是英 ...

  3. Python爬虫《爬取get请求的页面数据》

    一.urllib库 urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在Python3中的为urllib.request和urllib. ...

  4. IE浏览器下的渐变背景

    background: linear-gradient(to bottom, #000000 0%,#ffffff 100%);(标准) linear-gradient 在 ie9 以下是不支持的,所 ...

  5. 在Eclipse安装Genymotion插件的经验心得

    个人心得分享,不当之处还请指正. Eclipse自带的Android模拟器已经无力吐槽了,新手刚上手时或许配置完环境已经精疲力尽了,或许还沉浸在开发成功的喜悦当中,对AVD模拟器的运行情况关注不大,渐 ...

  6. Android 自定义倾斜字体

    public class RotateTextView extends AppCompatTextView { private static final int DEFAULT_DEGREES = 0 ...

  7. CSS样式编写案例

    1.制作如图三角形效果: 步骤一:将右侧盒子设置为相对定位 步骤二:在右侧盒子里面新建个子盒子,设置宽高相等,为正方形,绝对定位 步骤三:将绝对定位的盒子用CSS3旋转属性旋转 2.制定如图的序列号 ...

  8. mvc4 坑啊

    昨天下午出了个BUG.到今天上午才解决掉.就是mvc页面的属性名跟controller 中action 参数的名相同.导致action无法取得前台的值.这个问题浪费了很多时间.命名要规范. 如 页面 ...

  9. (原创)攻击方式学习之(3) - 缓冲区溢出(Buffer Overflow)

    堆栈溢出 堆栈溢出通常是所有的缓冲区溢出中最容易进行利用的.了解堆栈溢出之前,先了解以下几个概念: 缓冲区 简单说来是一块连续的计算机内存区域,可以保存相同数据类型的多个实例. 堆栈     堆 栈是 ...

  10. 配置一个高效快速的Git环境

    username and email editor difftool and mergetool alias 可以直接修改~/.gitconfig文件,也可以用命令配置一个可以实际使用的高效的Git环 ...