目的是:數據庫
利用rest_framework實現對數據庫內容的查看get請求(序列化)、提交保存數據post請求 (反序列化)django
rest_framework序列化組件(即查看和)json
第一步:基於Django搭建RESTful框架api
第二步:配置信息瀏覽器
settings.py配置app
settings裏面全局解析器:框架
1 #設置解析器(對發送過來的數據信息格式進項校驗並作進一步處理) 2 #全局能夠配好多個,局部配一個就行(先走局部的) 3 REST_FRAMEWORK = { 4 'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser'] 5 }
views.py局部解析器:post
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裏面的設置:ui
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配置:spa
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