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具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务 ...
随机推荐
- hibernateHQL语句
一.hql 1. 什么是hql HQL是Hibernate Query Language的缩写 查全部 2. hql和sql区别/异同 HQL SQL 类名/属性 表名/列名 区分大小写,关键字不区分 ...
- linux下递归删除目录下所有exe文件---从删库到跑路篇
linux下递归删除目录下所有exe文件 find . -name '*.exe' -type f -print -exec rm -rf {} \; (1) "." 表示从当前目 ...
- python的tecplot模块(tecplot新特性)
Python的tecplot模块仅支持tecplot2017以上 首先安装tecplot2017 安装完成以后,安装python的tecplot模块 可以通过终端转入tecplot安装目录下的pyte ...
- git之fatal: Could not read from remote repository
问题背景:在git bash中使用hexo g -d命令进行文章发布 详细错误信息: fatal: Could not read from remote repository. Please make ...
- thread 线程分析工具
(1) https://fastthread.io/ 将线程 jstack pid 出来之后,压缩一下成为zip 然后 上传上去
- Java-内存模型 synchronized 的内存语义
synchronized 具有使每个线程依次排队操作共享变量的功能.这种同步机制效率很低,但 synchronized 是其它并发容器实现的基础. 一.锁对象及 synchronized 的使用 sy ...
- Netty 多客户端连接与通信
实现场景: 聊天 服务端,客户端A,客户端B,客户端C.当客户端发送消息给服务端后,服务端在将这条消息广播个所有客户端户端A,客户端B,客户端C. 需求1: 客户端上线后,会通知所有客户端上线. 如客 ...
- MySql通过数据库文件恢复数据库
以表”Table”为例: 如类型是MyISAM, 数据文件则以”Table.frm””Table.MYD””Table.MYI””三个文件存储于”/data/$databasename/”目录中. 如 ...
- remaining connection slots are reserved for non-replication superuser connections
使用客户端工具连接pg,连接失败,报错以下错误: FATAL: remaining connection slots are reserved for non-replication superuse ...
- idea搭建简单ssm框架的最详细教程(新)
为开发一个测试程序,特搭建一个简单的ssm框架,因为网上看到很多都是比较老旧的教程,很多包都不能用了,eclipes搭建并且其中还附带了很多的其他东西,所以特此记录一下mac中idea搭建过程. 另: ...