Django框架深入了解_02(DRF之序列化、反序列化)
阅读目录
序列化:将Python对象准换成json格式的字符串,反之即为反序列化
DRF的序列化使用过程:
使用drf的序列化组件
-1 新建一个序列化类继承Serializer
-2 在类中写要序列化的字段
-在视图中使用序列化的类
-1 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
-2 对象.data
-3 return Response(对象.data)
使用示例:
新建Django项目:settings.py文件注册rest_framework,使用MySQL数据库创建数据
--------------------------------------------------------------------
注:如果你对python感兴趣,我这有个学习Python基地,里面有很多学习资料,感兴趣的+Q群:895817687
--------------------------------------------------------------------# settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'drf_ser01','HOST': '127.0.0.1','PORT': 3306,'USER': 'root','PASSWORD': '123'}
}# __init__.py
import pymysql
pymysql.install_as_MySQLdb()
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')
app01新建MySer.py
# 先创建一个BookSer序列化类
from rest_framework import serializersclass 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 viewsurlpatterns = [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 serializersclass 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.Bookfields = ('__all__')
如果只想取其中几个字段,可以进行指定:
# 序列化方式二:
class BookSer(serializers.ModelSerializer):class Meta:model = models.Bookfields = ['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 = (('1', 'Super_Admin'), ('2', 'General_Admin'), ('3', 'General_User') )user_type = models.CharField(max_length=6, choices=choices, default='3')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中重写createbook.create(book.validated_data)return Response(response)
# MySer.pyclass BookSer(serializers.Serializer):# read_only 反序列化的时候,该字段不传# 这里id可以不传自增,publish、author不传,当然需要在models里面把不传字段设置为null=True# author多对多字段不能设置null=Trueid = 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 = (('1', 'Super_Admin'), ('2', 'General_Admin'), ('3', 'General_User') )user_type = models.CharField(max_length=6, choices=choices, default='3')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.Bookfields = "__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.pyfrom rest_framework.exceptions import ValidationError
class BookSer(serializers.ModelSerializer):class Meta:model = models.Bookfields = "__all__"def validate_title(self, value):if value.startswith('sb'):raise ValidationError('不能以sb开头')return valuedef 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控制、解析器、响应器、版本控制、分页)(二)
解析器介绍: 所谓解析器,就是前端传过来的数据,后端可以解析,从request.data中取出来,默认的解析器配置是三种编码格式都可以取 回到顶部 解析器的作用: 根据请求头(content-type ...
- Django框架深入了解_04(DRF之url控制、解析器、响应器、版本控制、分页)(一)
阅读目录 一.url控制 基本路由写法:最常用 第二种写法:继承ModelViewSet 第三种写法:(自动生成路由,必须继承ModelViewSet) 二.解析器 前端不同的数据格式请求,后端解析得 ...
- Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)
阅读目录 一.认证组件 使用方法: token简单描述: 应用token编写登录接口: 二.权限组件 使用方法: 三.频率组件 使用方法: 一.认证组件 回到顶部 使用方法: ①写一个认证类,新建文件 ...
- Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)
阅读目录 一.Django请求生命周期: 二.WEB开发模式: 三.cbv源码分析: 四.认识RESTful 补充知识:跨域 五.基于原生django开发restful的接口 六.drf安装.使用.A ...
- Django框架之DRF框架
文章目录 一.前言 1.Web应用模式 2.RESTful API规范 二.简介 三.安装与配置 四.序列化器 1.创建序列化器 2.序列化操作 1)序列化过程 2)反序列化过程 3.校验规则 1)单 ...
- Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)
12.4 Cookie和Session 12.41 cookie Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务 ...
- 第三百零九节,Django框架,models.py模块,数据库操作——F和Q()运算符:|或者、并且——queryset对象序列化...
第三百零九节,Django框架,models.py模块,数据库操作--F()和Q()运算符:|或者.&并且 F()可以将数据库里的数字类型的数据,转换为可以数字类型 首先要导入 from dj ...
- 初学者Django框架的基本使用,以及项目部署(Docker部署)
Django框架 Django是Python Web应用框架, 基于Python的WSGI(Web Service Gateway Interface)Web服务网关接口, Django从3.0开始运 ...
- Django - Django框架 简单介绍
Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码 ...
最新文章
- linux命令find命令详解
- 微信小程序动画无限循环 掉花
- SAP WM初阶之2-Step Picking创建的Group查询报表
- 写入指定长度的字节到文件
- javaWeb服务详解(含源代码,测试通过,注释) ——applicationContext-Service.xml
- Django基础之中间件
- 保定2021高考成绩查询,保定2021年中考网上查询
- 学习web前端前景怎么样?
- 2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)
- JAVA 导出 Excel, JS 导出 Excel
- it职位简称_IT行业常见职位英文缩写
- 互动派年会-comsol专题超强干货剖析
- openwrt在mt7620a上的折腾笔记
- Photoshop设计精讲精练(读书笔记)
- 项目管理与SSM框架——Spring
- PS-把长方形图片改为正方形图片
- 找工作就上智联,效果真快,然而让我去的公司都是泡我呢
- python如何读取log文件_怎么解决Python读取log文件时报错
- 图论(9)图的连通度
- 教资计算机报高中害死初中,教师资格证报名入口必须电脑登录吗_中小学教师资格考试网...