序列化:将Python对象准换成json格式的字符串,反之即为反序列化

DRF的序列化使用过程:

使用drf的序列化组件
-1 新建一个序列化类继承Serializer
-2 在类中写要序列化的字段

-在视图中使用序列化的类
-1 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
-2 对象.data
-3 return Response(对象.data)

使用示例:

新建Django项目:settings.py文件注册rest_framework,使用MySQL数据库创建数据

# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'drf_ser01',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': ''
}
} # __init__.py
import pymysql
pymysql.install_as_MySQLdb()

MySQL数据库连接

from django.db import models

# Create your models here.

class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=1, max_digits=6)
publish = models.ForeignKey(to='Publish')
author = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author')) class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64, null=True) class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField() class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')

models

app01新建MySer.py

# 先创建一个BookSer序列化类
from rest_framework import serializers class BookSer(serializers.Serializer):
id = serializers.CharField()
title = serializers.CharField()
publish = serializers.CharField()
author = serializers.CharField()

app01视图函数views.py中

from django.shortcuts import render,HttpResponse,redirect
from app01.MySer import BookSer
from rest_framework.response import Response
from rest_framework.views import APIView
from app01 import models # Create your views here. class Books(APIView):
response = {'code': 100, 'msg': '查询成功'}
def get(self, request):
books = models.Book.objects.all()
books_ser = BookSer(instance=books, many=True)
return Response(books_ser.data)

配路由:

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^books/', views.Books.as_view()),
]

(通过NaviCat创建图书数据,用于查询...)

使用Postman发送get请求,获取到数据库中所有图书信息

可以看出一对多和多对多的外键字段显示的是对象名字,下面进一步使用序列化,让信息显示更完善

-source:可以指定字段(name   publish.name),可以指定方法

-SerializerMethodField搭配方法使用(get_字段名字)                
publish_detail=serializers.SerializerMethodField(read_only=True)
def get_publish_detail(self,obj):
return {'name':obj.publish.name,'city':obj.publish.city}

更新版本BookSer

from rest_framework import serializers

class BookSer(serializers.Serializer):
id = serializers.CharField()
title = serializers.CharField()
publish = serializers.CharField(source='publish.name')
author = serializers.SerializerMethodField()
def get_author(self, obj):
authors = []
for author_obj in obj.author.all():
authors.append({'name': author_obj.name, 'age': author_obj.age})
return authors

补充:

-read_only:反序列化时,不传
-write_only:序列化时,不显示

以上是序列化的一种方式

下面看看序列化的另外一种方式:ModelSerializers:指定了表模型

            class Meta:
model=表模型
#要显示的字段
fields=('__all__')
fields=('id','name')
#要排除的字段
exclude=('name')
#深度控制
depth=1
-重写某个字段
在Meta外部,重写某些字段,方式同Serializers
# 序列化方式二:
class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ('__all__')

如果只想取其中几个字段,可以进行指定:

# 序列化方式二:
class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ['id', 'title']
# fields = ('__all__')

刚才看到__all__,序列化所有字段,查询到的数据里面publish和author都是对应id值,如果需要获取到对应publish和author的关联信息,可以在BookSer内,Meta外重新写字段,方式同serializers

# 序列化方式二:
class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
# fields = ['id', 'title']
fields = ('__all__')
publish = serializers.CharField(source='publish.name')
author = serializers.SerializerMethodField()
def get_author(self, obj):
authors = []
for author_obj in obj.author.all():
authors.append({'name': author_obj.name, 'age': author_obj.age})
return authors

改进:

class AuthorSer(serializers.Serializer):
id = serializers.CharField()
name = serializers.CharField()
age = serializers.CharField() # 序列化方式二改进:
class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
# fields = ['id', 'title']
fields = ('__all__')
publish = serializers.CharField(source='publish.name')
author = serializers.SerializerMethodField()
def get_author(self, obj):
ret = AuthorSer(obj.author.all(), many=True)
return ret.data

通过post请求新增数据:

对数据进行新增使用反序列化实现,这里反序列化有2种情况进行新增:

使用继承了Serializers序列化类的对象,反序列化(需重写create方法)
from django.db import models

# Create your models here.

class User(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
choices = (('', 'Super_Admin'), ('', 'General_Admin'), ('', 'General_User') )
user_type = models.CharField(max_length=6, choices=choices, default='') class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=1, max_digits=6)
publish = models.ForeignKey(to='Publish', null=True)
author = models.ManyToManyField(to='Author') class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64, null=True) class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
class Book(APIView):
def post(self, request):
response = {'code': 100, 'msg': '新增成功'}
# 使用继承了Serializers序列化类的对象,反序列化
book = BookSer(data=request.data)
if book.is_valid():
# 清洗通过的数据,需要在MySer.py中重写create
book.create(book.validated_data)
return Response(response)
# MySer.py

class BookSer(serializers.Serializer):
# read_only 反序列化的时候,该字段不传
# 这里id可以不传自增,publish、author不传,当然需要在models里面把不传字段设置为null=True
# author多对多字段不能设置null=True
id = serializers.CharField(read_only=True)
title = serializers.CharField()
price = serializers.CharField()
publish = serializers.CharField(source='publish.id', read_only=True)
author = serializers.SerializerMethodField(read_only=True)
def get_author(self, obj):
ret = AuthorSer(obj.author.all(), many=True)
return ret.data
# 重写create方法,才能在使用Serializer发序列化方法进行新增数据
def create(self, validated_data):
res = models.Book.objects.create(**validated_data)
return res
使用继承了ModelSerializers序列化类的对象,反序列化
from django.db import models

# Create your models here.

class User(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
choices = (('', 'Super_Admin'), ('', 'General_Admin'), ('', 'General_User') )
user_type = models.CharField(max_length=6, choices=choices, default='') class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=1, max_digits=6)
publish = models.ForeignKey(to='Publish', null=True)
author = models.ManyToManyField(to='Author') class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64, null=True) class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
class Book(APIView):

    def post(self, request):
response = {'code': 100, 'msg': '新增成功'} # 使用继承了ModelSerializers序列化类的对象,反序列化
book_ser = BookSer(data=request.data)
if book_ser.is_valid():
book_ser.save()
else:
response['error'] = book_ser.errors['name'][0]
return Response(response)

 使用ModelSerializer反序列化save数据后,多对多关联的那张表也会自动关联产生新的数据。

局部校验和全局校验
# MySer.py

from rest_framework.exceptions import ValidationError
class BookSer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__" def validate_title(self, value):
if value.startswith('sb'):
raise ValidationError('不能以sb开头')
return value def validate(self, attrs):
title = attrs.get('title')
price = attrs.get('price')
if title.startswith('禁书') or int(price) <= 15:
raise ValidationError('书名或价格不正常')
return attrs

总结:

-反序列化的校验
-validate_字段名(self,value):
-如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
-如果校验通过直接return value
-validate(self,attrs)
-attrs所有校验通过的数据,是个字典
-如果校验失败,抛出ValidationError
-如果校验通过直接return attrs

 

Django框架深入了解_02(DRF之序列化、反序列化)的更多相关文章

  1. Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)

    一.url控制 基本路由写法:最常用 from django.conf.urls import url from django.contrib import admin from app01 impo ...

  2. Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)

    一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...

  3. django框架-DRF视图中的request和response

    1.Request 相对于django框架,DRF工程的request类则是继承自HttpRequest类,Rest framework提供了parser解释器,用来解释请求中的content_typ ...

  4. Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)

    一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...

  5. DRF框架之使用Django框架完成后端接口(API)的定义

    学习DRF框架,首先我们就需要明白为什么要学习这个框架. 接下来我们就先用原生的Django框架来定义一个符合RESTful设计方法的接口(API). RESTful接口的需求如下: GET /boo ...

  6. 第三百零九节,Django框架,models.py模块,数据库操作——F和Q()运算符:|或者、&并且——queryset对象序列化

    第三百零九节,Django框架,models.py模块,数据库操作——F()和Q()运算符:|或者.&并且 F()可以将数据库里的数字类型的数据,转换为可以数字类型 首先要导入 from dj ...

  7. Django框架之DRF APIView Serializer

    一.APIView 我们在使用DjangoRestfulFramework的时候会将每个视图类继承APIView,取代原生Django的View类 APIView的流程分析: rest_framewo ...

  8. Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程

    一.序列化类的增.删.改.查 用drf的序列化组件   -定义一个类继承class BookSerializer(serializers.Serializer):   -写字段,如果不指定source ...

  9. Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)

    12.4 Cookie和Session 12.41 cookie Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务 ...

随机推荐

  1. 集成omnibus-ctl 开发一个专业的软件包管理工具

    前边有转发过来自chef 团队的一篇omnibus-ctl 介绍文章,以下尝试进行项目试用 就是简单的集成,没有多少复杂的操作 环境准备 ruby ruby 使用2.6.3 使用 rbenv 安装,可 ...

  2. 用户价值和RFM模型

    什么是用户价值? 用户价值就是对公司来说有用的地方,比如有的公司看中用户的消费能力,有的公司则看中用户的忠诚度 .各公司的业务目的不同,用户价值的体现自然也不同.这里主要说一下适用于电商的RFM模型. ...

  3. 【luoguP4544】[USACO10NOV]购买饲料Buying Feed

    题目链接 首先把商店按坐标排序 \(dp_{i,j}\)表示前i个商店买了j吨饲料并运到终点的花费,二进制拆分优化转移 #include<algorithm> #include<io ...

  4. Koa Cookie 的使用

    Cookie 简介 cookie 是存储于访问者的计算机中的变量.可以让我们用同一个浏览器访问同一个域 名的时候共享数据. HTTP 是无状态协议.简单地说,当你浏览了一个页面,然后转到同一个网站的另 ...

  5. CentOS7 通过systemd 添加开机重启服务

    现在越来越多的环境采用 CentOS 7 作为基础配置,特别是 Hadoop生态 如果要测试或部署环境需要启动很多组件(zookeeper.kafka.redis等等),如下内容是在操作系统层实现开机 ...

  6. 刷题记录:2018HCTF&admin

    目录 刷题记录:2018HCTF&admin 一.前言 二.正文 1.解题过程 2.解题方法 刷题记录:2018HCTF&admin 一.前言 经过一个暑假的学习,算是正经一条web狗 ...

  7. 在IDEA上对SpringBoot项目配置Devtools实现热部署

    spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. devtool ...

  8. 第10组 Beta冲刺(4/5)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...

  9. 团队作业-Alpha(2/4)

    队名:软工9组 组长博客:https://www.cnblogs.com/cmlei/ 作业博客:http://edu.cnblogs.com/campus/fzu/SoftwareEngineeri ...

  10. 电商ERP系统——商品SKU与库存设计

    面试题经常问道,如何设计库存,哪些库存呢?分类属性的库存:不同颜色 不同尺码的属性的库存,这时候需要针对具体的SKU商品创建表. 总体思路 1.商品关联商品类别,商品类别关联多个商品属性,其中指定某几 ...