序列化组件:Serializer、ModelSerializer、ListModelSerializer

Serializer  偏底层  ModelSerializer       重点  ListModelSerializer     辅助群改

1.Serializer组件

(1)准备

(1)models.py中

class User(models.Model):
SEX_CHOICES = [
[0,”男”], #前面是0还是”0”和IntergerField还是CharField有关
[1,”女”] #前面是填入的,后面是显示的
]
name = models.CharField(max_length=64)
pwd = models.CharField(max_length=32)
phone = models.CharField(max_length=11, null=True, default=None)
sex = models.IntegerField(choices=SEX_CHOICES, default=0)
icon = models.ImageField(upload_to=”icon”, defult=’icon/defult.png’) #需要在项目base目录下新建media文件夹,然后在media下建立icon文件夹
  (默认会找media下的icon文件夹)
class Meta:
db_table = ‘yq_user’
verbose_name = “用户表”
verbose_name_plural = verbose_name
def __str__(self):
return “%s”%self.name

(2)在admin.py下注册User

admin.site.register(models.User)

(3)在shell中迁移

makemigrations、migrate

get请求是要序列化,将后台数据返回给前台;post请求要反序列化,将前台数据给后台存入数据库中,同时也要序列化对象展示数据给前台。

(4)配置媒体资源

1)在settings.py里配置media路径

MEDIA_ROOT = os.path.join(BASE_DIR, ‘media’)

2)在项目文件下的urls.py中

#media在根路由配置

from django.views.static import serve
from django.conf import setting urlpatterns = [
...
url(r”^media/(?P<path>.*)”, serve, {‘document_root’: setting.MEDIA_ROOT}) #正则匹配时不要写$,可以一层层找
]

3)数据库再迁移下

用户对象(model对象或者query_set对象)、用户对象列表不能直接返回给前台,要序列化下对象。因此要用Serializer。

(2)序列化

(1)配置路由

urlpatterns = [
url(r'^users/$', views.User.as_view()),
url(r'^users/(?P<pk>.*)/$', views.User.as_view()),
]

(2)自定义序列化类。在应用文件夹下新建serializers.py文件。

序列化组件的工作方式与django的forms组件相似

from rest_framework import serializers

class UserSerailizer(serializers.Serializer):

  #字段的类型和定义时一致,字段为想要返回给前台的内容(pwd不用返回就不写)
  name = serializers.CharField() #序列化的括号里不需加条件
  phone = serlializers.CharField()
  #sex = serializers.IntegerField()
  #icon = serializers.ImageField()   #由于sex默认返回的是0、1数字给前台,icon返回的不是全链接,因此要自定义序列化属性:定制返回的内容   gender = serializers.SerializerMethodField() #可以叫gender,也可以叫sex,不一定与字段名保持一致   def get_gender(self, obj): #必须以get开头,后面也必须和上面的gender对应
  #self是serializer对象,obj是模型类对象
    return obj.get_sex_display() #get_xxx_display() 表示取到选项值   #在settings.py中配置下MEDIA_URL = /media/
  from untitled1 import settings
  img = serializer.SerializerMethodField()
  def get_img(self, obj):
    return “%s%s%s”%(r”http://127.0.0.1:8000”, settings.MEDIA_URL, str(obj.icon))
  #obj.icon不能直接作为数据返回,类型是ImageFile类型,可以通过str转化为str类型。

(3)在views.py中返回对象序列化后的json数据

from . import serializers
from rest_framework.views import APIView
from rest_framework.response import Response class User(APIView): def get(self, request, *args, **kwargs):
pk = kwargs.get('pk') #通过有名分组匹配到的路径参数
if pk: #单查
try:
user_obj = models.User.objects.get(pk=pk) #取到model对象
#将对象序列化取得dict数据
user_ser_data = serializers.UserSerializer(user_obj).data
return Response({
"status": 0,
"msg": "ok",
"results": user_ser_data
})
except:
return Response({
"status": 2,
"msg": "no user",
})
else: #群查
user_obj_list = models.User.objects.all()
       #将对象列表序列化
user_ser_data = serializers.UserSerializer(
user_obj_list,many=True).data
return Response({
"status": 0,
"msg": "ok",
"results":user_ser_data
})

总结:

序列化ser:

1)序列化给前台的字段个数可以由后台自己决定,但是提供的序列化字段的一定要和数据库的字段的类型和名字一致。

2)自定义属性名:为了返回自定义的字段的值。属性名随意,值由固定的命名规范方法提供:get_属性名(self, obj)。obj为参与序列化的model或者query_set对象。返回值就是自定义序列化属性的值。

view:

1)从数据库中将要序列化给前台的model对象,或是多个model对象查询出来

user_obj = models.User.objects.get(pk=pk)或者

user_objs_list = models.User.objects.all()

2)将对象交给序列化处理,产生序列化对象,如果序列化的是多个数据,要设置many=True

user_ser = serializers.UserSerializer(user_obj)或者

user_ser_list = serializers.UserSerializer(user_objs_list, many=True)

3)序列化对象.data就是可以返回给前台的序列化数据,然后return Response返回

(3)反序列化

反序列化考虑的问题:

1)哪些字段必须反序列化

2)字段都有哪些安全校验

3)哪些字段需要提供额外的安全校验

4)哪些字段间存在联合校验

反序列化字段全都是用来入库的,不会出现自定义方法属性,但会出现设置校验规则(系统校验、局部钩子和全局钩子)的自定义属性(如re_pwd)

(1)还是在刚才的serializers.py文件中

class UserDeserializer(serializer.Serializer):

  name = serializers.CharField(
   required=True,
   max_length=64, #自定义检验规则
   min_length=3,
   error_message = { #错误信息,不给是默认的
       ‘max_length’:’太长’,
      ‘min_length’:’太短’,
})
  pwd= serializers.CharField(required=True)
  phone = serializers.CharField(required=False)
  sex = serializers.IntegerField(required=False)   #自定义有校验规则的反序列化字段。不存入库,只是用来校验
  re_pwd = serializers.CharField(required=True) #用来判断两次输入密码一样   #局部钩子:validate_要校验的字段名(self, 当前要检验字段的值)
  #校验规则:校验成功返回原值,失败返回异常
  #局部钩子校验某个字段
  def validate_name(self, value):
    if ‘j’ in value.lower(): #名字中不能出现j
     #from rest_framework import exceptions
      raise exceptions.ValidationError(“名字非法”)
    return value #必须返回,校验成功返回value,失败抛异常   #全局钩子:固定写法validate(self, attrs)。attrs为系统与局部钩子校验通过的所有数据。(系统和全局之间还有个局部钩子)
  #校验时需要用到多个字段。比如两次密码输入一致
  #校验规则:校验成功返回原值,失败返回异常
  def validate(self, attrs):
    pwd = attrs.get(‘pwd’) #只是取得
    re_pwd = attrs.pop(‘re_pwd’) #取得并且删除(不需要入库)
    if pwd != re_pwd:
      raise exceptions.ValidationError({“pwd“: “两次密码不一致”})
    return attrs #必须返回,校验成功返回attrs,失败抛异常   #要完成新增,需在serializers.py中的自定义反序列化类中重新create方法。
  def create(self, validated_data): #在views.py中校验后,save方法调用时内部会调用create。
    #在所有校验规则完毕之后,数据(validated_data是已经校验好的数据)可以直接入库
    #from . import models
    return models.User.objects.create(**validated_data)

(2)在views.py下 的User类下写post方法(对post提交的数据反序列化)

def post(self, request, *args, **kwargs):
  request_data = request.data #字典
#数据是否合法(增加对象必须是一个字典数据且有值)
  if not isinstance(request_data, dict) or not request_data:
    return Response({
      "status": 1,
"msg": "数据有误",
        })
 #数据类型合法,但数据内容不一定合法,需要校验数据,校验的(参与反序列化)数据需要赋值给data
  book_ser = serializers.UserDeserializer(data=request_data) #必须关键字data赋值
  #序列化对象调用is_valid完成校验,校验失败信息存储在序列化对象.errors中
  if book_ser.is_valid():
    book_obj = book_ser.save() #校验通过,完成新增(save的返回值就是完成校验后create返回的对象)
    return Response({
      "status": 0,
"msg": "ok",
      "results":serializers.UserSerializer(book_obj).data
      #新增和修改,都要 将反序列化的对象 再序列化 返回给其前台
       })
  else: #校验没通过(校验的错误信息存在book_ser的errors中)
    return Response({
      "status": 1,
"msg": book_ser.errors,
})

反序列化总结:

视图类中:

1)把要校验的数据交给序列化类,由data接收;

book_ser = serializers.UserDeserializer(data=request_data)

2)走is_valid校验;

if book_ser.is_valid():

3)校验成功走save方法,校验失败返回errors。

book_obj = book_ser.save()

序列化类中:

1)设置必填与选填序列化字段,设置校验规则

2)为需要额外校验的字段提供局部钩子函数,如果某些字段(如验证码)不入库且不参与全局钩子,可以将值取出pop校验(一般在全局钩子里)

3)为有联合关系的字段们提供全局钩子。如果某些字段不入库,也取出pop校验(如二次输入的密码)

4)重写create方法,完成校验通过的字段入库,得到新增的对象。

ser = 自定义序列化类(instance=模型类对象, data=empty,  **kwargs)  #序列化时传入模型类对象(instance=可以不写,直接写对象),不需要写data(data是反序列化才有);**kwargs比如当对象是个列表时,可以加个many=True参数。

ser = 自定义反序列化类(instance=None, data=数据)   #将要被反序列化的前端传来的数据传入data中。

drf之序列化组件(一):Serializer的更多相关文章

  1. Django框架(十八)—— drf:序列化组件(serializer)

    序列化组件 # 模型层 from django.db import models class Book(models.Model): nid = models.AutoField(primary_ke ...

  2. Django框架(十九)—— drf:序列化组件(serializer)

    目录 序列化组件 一.利用for循环来实现序列化(繁琐) 二.利用Django提供的序列化组件(不可控需要的字段) 三.利用drf提供的序列化组件 1.基于Serializer类实现序列化--基本语法 ...

  3. 第三章、drf框架 - 序列化组件 | Serializer

    目录 第三章.drf框架 - 序列化组件 | Serializer 序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer( ...

  4. DRF的序列化组件

    目录 DRF的序列化组件 Serializer组件 序列化 反序列化 ModelSerializer组件 序列化和反序列化 自定义Response方法 基表相关 DRF中ORM的多表关联操作 外键设计 ...

  5. drf框架 - 序列化组件 | Serializer

    序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 序列化与反序列化 序列化: 将对象序列化成字符串用户传输 ...

  6. Django框架 --序列化组件(serializer)

    一 .Django自带序列化组件 Django内置的serializers(把对象序列化成json字符串) from django.core import serializers from djang ...

  7. drf 之序列化组件

    序列化 把Python中对象转换为json格式字符串 反序列化 把json格式转为为Python对象. 用orm查回来的数据都是都是一个一个的对象, 但是前端要的是json格式字符串. 序列化两大功能 ...

  8. DRF(3) - 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件

    一.序列化组件 基于上篇随笔的表结构,通过序列化组件的ModelSerializer设计如下三个接口: GET 127.0.0.1:8000/books/{id} # 获取一条数据,返回值:{} PU ...

  9. drf框架 - 序列化组件 | ModelSerializer (查,增,删,改)

    ModelSerializer 序列化准备: 配置 settings.py # 注册rest_framework框架 INSTALLED_APPS = [ ... 'rest_framework' ] ...

随机推荐

  1. 浅谈进程&线程

    学习过操作系统(下面简称OS)的都清楚,计算机计算的核心是CPU,操作系统是计算机资源的管理者 同事也是软硬件之间的接口.为了实现程序的并发,而引入了进程的概念.在传统OS中,进程是个很重要的概念,它 ...

  2. 【QT】利用pyqt5实现简单界面

    Topic: 利用pyqt5编写简单界面Env:win10 + Pycharm2018 + Python 3.6.8Date: 2019/4/29 by hw_Chen2018            ...

  3. html5学习之路_001

    安装环境 安装intellij idea作为开发环境 打开环境 新建一个html文件,打开之后出现代码框架,再次基础上继续编码即可,例如: <!DOCTYPE html> <html ...

  4. 中文分词工具——jieba

    汉字是智慧和想象力的宝库. --索尼公司创始人井深大 简介 在英语中,单词就是"词"的表达,一个句子是由空格来分隔的,而在汉语中,词以字为基本单位,但是一篇文章的表达是以词来划分的 ...

  5. 公有继承中派生类Student对基类Person成员的访问 代码参考

    #include <iostream> #include <cstring> using namespace std; class Person { private: char ...

  6. python3程序开发指南——第1章 笔记

    python文件的扩展名为.py ,但是python GUI程序的扩展名为.pyw 在python中,注释以#开始,作用范围为该行 IDLE提供了三个关键功能:输入python表达式与代码,并在pyt ...

  7. python调用大漠插件教程04鼠键事件及基本项目思维

    from win32com.client import Dispatch import os from random import uniform from time import sleep cla ...

  8. jupyter notebook 安装扩展nbextensions

    安装nbextensions可提高jupyter notebook效率,安装步骤如下: 1.pip 方式安装: (gluon) [root@localhost ~]# pip install jupy ...

  9. 判断IP地址的合法性

    每台计算机都有独一无二的编号,称为ip地址,每个合法的ip地址由‘.’分隔开的4个数字组成,每个数字的取值范围为0--255 输入一个字符串,判断其是否为合法的IP地址,若是输出‘YES’,否则输出‘ ...

  10. Java实现 LeetCode 791 自定义字符串排序(桶排序)

    791. 自定义字符串排序 字符串S和 T 只包含小写字符.在S中,所有字符只会出现一次. S 已经根据某种规则进行了排序.我们要根据S中的字符顺序对T进行排序.更具体地说,如果S中x在y之前出现,那 ...