Django框架深入了解_02(DRF之序列化、反序列化)
序列化:将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之序列化、反序列化)的更多相关文章
- Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)
一.url控制 基本路由写法:最常用 from django.conf.urls import url from django.contrib import admin from app01 impo ...
- Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)
一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...
- django框架-DRF视图中的request和response
1.Request 相对于django框架,DRF工程的request类则是继承自HttpRequest类,Rest framework提供了parser解释器,用来解释请求中的content_typ ...
- Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)
一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...
- DRF框架之使用Django框架完成后端接口(API)的定义
学习DRF框架,首先我们就需要明白为什么要学习这个框架. 接下来我们就先用原生的Django框架来定义一个符合RESTful设计方法的接口(API). RESTful接口的需求如下: GET /boo ...
- 第三百零九节,Django框架,models.py模块,数据库操作——F和Q()运算符:|或者、&并且——queryset对象序列化
第三百零九节,Django框架,models.py模块,数据库操作——F()和Q()运算符:|或者.&并且 F()可以将数据库里的数字类型的数据,转换为可以数字类型 首先要导入 from dj ...
- Django框架之DRF APIView Serializer
一.APIView 我们在使用DjangoRestfulFramework的时候会将每个视图类继承APIView,取代原生Django的View类 APIView的流程分析: rest_framewo ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)
12.4 Cookie和Session 12.41 cookie Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务 ...
随机推荐
- 集成omnibus-ctl 开发一个专业的软件包管理工具
前边有转发过来自chef 团队的一篇omnibus-ctl 介绍文章,以下尝试进行项目试用 就是简单的集成,没有多少复杂的操作 环境准备 ruby ruby 使用2.6.3 使用 rbenv 安装,可 ...
- 用户价值和RFM模型
什么是用户价值? 用户价值就是对公司来说有用的地方,比如有的公司看中用户的消费能力,有的公司则看中用户的忠诚度 .各公司的业务目的不同,用户价值的体现自然也不同.这里主要说一下适用于电商的RFM模型. ...
- 【luoguP4544】[USACO10NOV]购买饲料Buying Feed
题目链接 首先把商店按坐标排序 \(dp_{i,j}\)表示前i个商店买了j吨饲料并运到终点的花费,二进制拆分优化转移 #include<algorithm> #include<io ...
- Koa Cookie 的使用
Cookie 简介 cookie 是存储于访问者的计算机中的变量.可以让我们用同一个浏览器访问同一个域 名的时候共享数据. HTTP 是无状态协议.简单地说,当你浏览了一个页面,然后转到同一个网站的另 ...
- CentOS7 通过systemd 添加开机重启服务
现在越来越多的环境采用 CentOS 7 作为基础配置,特别是 Hadoop生态 如果要测试或部署环境需要启动很多组件(zookeeper.kafka.redis等等),如下内容是在操作系统层实现开机 ...
- 刷题记录:2018HCTF&admin
目录 刷题记录:2018HCTF&admin 一.前言 二.正文 1.解题过程 2.解题方法 刷题记录:2018HCTF&admin 一.前言 经过一个暑假的学习,算是正经一条web狗 ...
- 在IDEA上对SpringBoot项目配置Devtools实现热部署
spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. devtool ...
- 第10组 Beta冲刺(4/5)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...
- 团队作业-Alpha(2/4)
队名:软工9组 组长博客:https://www.cnblogs.com/cmlei/ 作业博客:http://edu.cnblogs.com/campus/fzu/SoftwareEngineeri ...
- 电商ERP系统——商品SKU与库存设计
面试题经常问道,如何设计库存,哪些库存呢?分类属性的库存:不同颜色 不同尺码的属性的库存,这时候需要针对具体的SKU商品创建表. 总体思路 1.商品关联商品类别,商品类别关联多个商品属性,其中指定某几 ...