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

 

posted @ 2018-10-14 23:17  yangzhizong  阅读(2757)  评论(1编辑  收藏  举报