RESTful-rest_framework应用第二篇(get、post的序列化与反序列化)
目的是:
利用rest_framework实现对数据库内容的查看get请求(序列化)、提交保存数据post请求 (反序列化)
rest_framework序列化组件(即查看和)
第一步:基于Django搭建RESTful框架
第二步:配置信息
settings.py配置
settings里面全局解析器:
1 #设置解析器(对发送过来的数据信息格式进项校验并做进一步处理) 2 #全局可以配好多个,局部配一个就行(先走局部的) 3 REST_FRAMEWORK = { 4 'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser'] 5 }
views.py局部解析器:
1 #JSONParser,FormParser局部解析器,一般只需要写一个就行 2 from rest_framework.parsers import JSONParser,FormParser 3 class Book(APIView): 4 5 #解析器:对浏览器发送post请求过来的数据类型做解析 6 #当指向下面post请求,运行request.data的时候才会去执行解析器 7 parser_classes = [JSONParser,FormParser] 8 9 def get(self,request): #request是已经处理好的request 10 11 ret = models.Book.objects.all() 12 print(ret,type(ret)) #ret是QuerySet对象 <class 'django.db.models.query.QuerySet'> 13 14 # 实例化上面的BookSerializer拿到一个book_ser对象 15 # BookSerializer参数(ret:queryset对象,many=True代表序列化多条,many=False 代表序列化一条) 16 book_ser=BookSerializer(ret,many=True) 17 #book_ser.data不是json格式的字符串,而是个字典 18 #所以Response内部一定是对book_ser.data做了序列化 19 return Response(book_ser.data) 20 21 22 def post(self,request): 23 print('111') 24 print(request.data) 25 return HttpResponse('ok') 26 27 # 杂乱内容整理: 28 # print(request.POST) 29 #对请求过来的数据进项验证,检验每个字段是否符合录入要求,并保存 30 ser = BookSerializer(data=request.data) 31 32 #post请求过来数据符合每个字段要求,就允许写入数据库 33 if ser.is_valid(): 34 ser.save() 35 return Response(ser.save()) 36 37 #不符合要求就返回错误信息 38 else: 39 print(ser.errors) 40 41 42 return HttpResponse(json.dumps(ser.errors))
models.py里面的设置:
1 from django.db import models 2 3 # Create your models here. 4 5 from django.db import models 6 7 class Book(models.Model): 8 title=models.CharField(max_length=32) 9 price=models.IntegerField() 10 pub_date=models.DateField() 11 publish=models.ForeignKey("Publish") 12 authors=models.ManyToManyField("Author") 13 14 def __str__(self): 15 return self.title 16 17 #我了验证可以覆盖重写字段的方法 18 def test(self): 19 return '555' 20 21 22 class Publish(models.Model): 23 name=models.CharField(max_length=32) 24 email=models.EmailField() 25 # def __str__(self): 26 # return self.name 27 28 class Author(models.Model): 29 name=models.CharField(max_length=32) 30 age=models.IntegerField() 31 def __str__(self): 32 return self.name
views.py配置:
1 from django.shortcuts import render,HttpResponse,redirect 2 import json 3 from api import models 4 # Create your views here. 5 6 # from api.models import Book 7 8 from rest_framework.views import APIView 9 from rest_framework import serializers 10 from rest_framework.response import Response 11 12 from rest_framework.serializers import SerializerMethodField 13 14 #为了验证方式三 15 class AuthorsSerializer(serializers.Serializer): 16 id = serializers.CharField() 17 name = serializers.CharField() 18 age = serializers.CharField() 19 20 class PublishSerializer(serializers.Serializer): 21 id = serializers.CharField() 22 name = serializers.CharField() 23 email = serializers.CharField() 24 25 #RESful提供的一个序列化组件BookSerializer,可以控制传入的参数 26 class BookSerializer(serializers.Serializer): 27 #指定字段重命名,例如:将title重命名为xx 28 xx = serializers.CharField(source='title') 29 #添加新字段:只要models里面指定一个test方法,就会执行并显示一条新的字段 30 qqq=serializers.CharField(source='test') 31 32 title=serializers.CharField() 33 price=serializers.CharField() 34 pub_date=serializers.DateField() 35 #publish是个object对象,所以可以.name查看里面的内容 36 publish=serializers.CharField(source="publish.name") 37 38 #查询所有作者: 39 #方式一: 40 authors=serializers.CharField(source="authors.all") 41 42 43 #方式二:for循环拿到作者对象 44 authors=serializers.SerializerMethodField() 45 def get_authors(self,obj): 46 ll=[] 47 for author in obj.authors.all(): 48 print(author) 49 ll.append({'name':author.name,'age':author.age}) 50 return ll 51 52 #方式三:将作者实例化 53 authors=serializers.SerializerMethodField() 54 def get_authors(self,obj): 55 ret_authors = obj.authors.all() 56 57 ser=AuthorsSerializer(ret_authors,many=True) 58 return ser.data 59 60 61 #方式四: 62 class BookSerializer(serializers.ModelSerializer): 63 class Meta: 64 #第一步:先拿到所有字段 65 model = models.Book 66 #__all__要去所有字段 67 fields = '__all__' 68 # 指定显示要取的字段 (注意指定和去除不能同时用) 69 # fields=('id','title') 70 # 去除某个或某几个字段不显示 71 # exclude=('id','publish') 72 73 # 重新tiltle字段,进行重命名 74 # xx = serializers.CharField(source='title') 75 76 #第二步:查看书对应的所有作者,(再重写authors字段,让其所以作者信息,而不只是显示序列号) 77 authors=serializers.SerializerMethodField() 78 def get_authors(self,obj): 79 ret_authors = obj.authors.all() 80 # print(ret_authors,type(ret_authors)) 81 82 ser=AuthorsSerializer(ret_authors,many=True) 83 return ser.data 84 85 #同理,查看书对应的的出版社 86 publish=serializers.SerializerMethodField() 87 def get_publish(self,obj): 88 ret_publish= obj.publish 89 print(ret_publish,type(ret_publish)) #Publish object 90 ser = PublishSerializer(ret_publish,many=False) 91 print(ser.data) 92 return ser.data 93 94 95 96 #设置title字段为必填字段,并设计中文提示信息 97 title = serializers.CharField(error_messages={'required':'标题为必填字段'}) 98 99 100 #字段校验和反序列化: 101 102 #局部钩子:用来校验1个字段 103 def validate_title(self,value): 104 from rest_framework.exceptions import ValidationError 105 print(value) 106 # raise ValidationError('就是看你不爽') 107 return value 108 109 #全局钩子:多个字段间对比检验 110 def validate(self,attrs): 111 from rest_framework.exceptions import ValidationError 112 if attrs.get('title') == attrs.get('price'): 113 return attrs 114 else: 115 raise ValidationError('书名和价格不一样') 116 117 118 119 120 class Book(APIView): 121 def get(self,request): 122 ret = models.Book.objects.all() 123 # BookSerializer可以获取请求的数据 124 book_ser = BookSerializer(ret,many=True) 125 print(book_ser.data) 126 return Response(book_ser.data) 127 #post请求,及实现保存数据 128 def post(self,request): 129 # BookSerializer也可以保存数据信息到数据库 130 ser=BookSerializer(data=request.data) 131 if ser.is_valid(): 132 ser.save() 133 return HttpResponse('提交的post请求数据符合要求,已成功录入后台') 134 135 else: 136 print(ser.errors) 137 # return Response(ser.errors) 138 return HttpResponse(json.dumps(ser.errors)) 139 140 141 142 143 144 145 #RESTfu自带的处理请求的模块方法 146 #JSONParser,FormParser局部解析器,一般只需要写一个就行 147 from rest_framework.parsers import JSONParser,FormParser 148 class Book(APIView): 149 150 #解析器:对浏览器发送post请求过来的数据类型做解析 151 #当指向下面post请求,运行request.data的时候才会去执行解析器 152 parser_classes = [JSONParser,FormParser] 153 154 def get(self,request): #request是已经处理好的request 155 156 ret = models.Book.objects.all() 157 print(ret,type(ret)) #ret是QuerySet对象 <class 'django.db.models.query.QuerySet'> 158 159 # 实例化上面的BookSerializer拿到一个book_ser对象 160 # BookSerializer参数(ret:queryset对象,many=True代表序列化多条,many=False 代表序列化一条) 161 book_ser=BookSerializer(ret,many=True) 162 #book_ser.data不是json格式的字符串,而是个字典 163 #所以Response内部一定是对book_ser.data做了序列化 164 return Response(book_ser.data) 165 166 167 def post(self,request): 168 print('111') 169 print(request.data) 170 return HttpResponse('ok') 171 172 # 杂乱内容整理: 173 # print(request.POST) 174 #对请求过来的数据进项验证,检验每个字段是否符合录入要求,并保存 175 ser = BookSerializer(data=request.data) 176 177 #post请求过来数据符合每个字段要求,就允许写入数据库 178 if ser.is_valid(): 179 ser.save() 180 return Response(ser.save()) 181 182 #不符合要求就返回错误信息 183 else: 184 print(ser.errors) 185 186 187 return HttpResponse(json.dumps(ser.errors))
知识点分解,如下:
rest-framework序列化之ModelSerializer
1 class BookSerializer(serializers.ModelSerializer): 2 class Meta: 3 #第一步:先拿到所有字段 4 model = models.Book 5 #__all__要去所有字段 6 fields = '__all__' 7 # 指定显示要取的字段 (注意指定和去除不能同时用) 8 # fields=('id','title') 9 # 去除某个或某几个字段不显示 10 # exclude=('id','publish') 11 12 #下面这个方法不建议使用(因为不是字段都是要展示给客户看的,还是要使用下面那个方法,可以指定显示哪些字段) 13 # depth = 1 #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层 14 15 # 重新tiltle字段,进行重命名 16 # xx = serializers.CharField(source='title') 17 18 #第二步:查看书对应的所有作者,(再重写authors字段,让其所以作者信息,而不只是显示序列号) 19 authors=serializers.SerializerMethodField() 20 def get_authors(self,obj): #obj是一个book对象 21 ret_authors = obj.authors.all() 22 # print(ret_authors,type(ret_authors)) 23 24 ser=AuthorsSerializer(ret_authors,many=True) 25 return ser.data 26 27 #同理,查看书对应的的出版社 28 publish=serializers.SerializerMethodField() 29 def get_publish(self,obj): 30 ret_publish= obj.publish 31 print(ret_publish,type(ret_publish)) #Publish object 32 ser = PublishSerializer(ret_publish,many=False) 33 print(ser.data) 34 return ser.data