DRF框架之 serializers 序列化組件
阿新 • • 發佈:2019-04-27
city 反序 hone clu 簡單 ace .... lds splay
1. 什麽是序列化,其實在python中我們就學了序列化工具json工具,就是吧信息存為類字典形式
2. DRF框架自帶序列化的工具: serializers
3. DRF框架 serializers 分為:第一種 Serializer 第二種 ModelSerializer
第一種用法之 Serializer
from django.db import models # Create your models here. class Book(models.Model): nid = models.AutoField(primary_key=True) namemodels層先創建數據表= models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField() publish = models.ForeignKey(to=‘Publish‘,to_field=‘nid‘,on_delete=models.CASCADE) authors=models.ManyToManyField(to=‘Author‘) def __str__(self):return self.name def test(self): #註意: 這裏是給後面序列化組件的source指定方法用的 return str(self.price)+self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to=‘AuthorDatail‘,to_field=‘nid‘,unique=True,on_delete=models.CASCADE) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name
from rest_framework import serializers from app.models import Book,Author ####################這裏是serializers 實例化方法一的實現 # class Bookserializer(serializers.Serializer): # 這裏是通過rest_framwork 來實例化對象中的內容,返回給前端的數據信息 id = serializers.CharField() # source指定數據庫中的名字,前面可以自定義名字來使用,給前端顯示的是自定義名字 bookname 是自己自定義的名字 bookname = serializers.CharField(source=‘name‘) price = serializers.CharField() # source還可以通過對象繼續點其他屬性, 可以跨表點其他的想要的屬性(這個只是拿到publish的單個字段) publish_name = serializers.CharField(source=‘publish.name‘) #註意source 還可以調用models中 Book 表內的方法 maxprice = serializers.CharField(source=‘test‘) #註意,source 可以名字自定義顯示,可以跨表鏈接其他想要的屬性,還可以調用book表中的自定義的方法 # publish字段,返回出版社的所有信息,包括id,name,email。。。。 # #SerializerMethodField配合一個方法,方法的返回值會付給publish #SerializerMethodField 可以拿到跨表內的多個字段,你吧想要的都返還回去就行了(這裏是拿到publish的多個字段信息) publish = serializers.SerializerMethodField() #這裏這裏的obj 是當前序列化的對象 這裏的對象就是book!!!! def get_publish(self,obj): return {‘id‘:obj.publish.pk, ‘name‘: obj.publish.name,‘city‘:obj.publish.city} ####################這裏是serializers 實例化方法一的實現自己創建個py文件,寫上序列化顯示的內容
第二種用法之ModelSerializer
###################這裏是serializers實例化實現方法二 的實現,調用ModelSerializer class Bookserializer(serializers.ModelSerializer): #這裏一個meta類去調用Book這個表 class Meta: model = models.Book #fields 是然他顯示所有的內容,渲染出去 fields = "__all__" # ‘__all__‘ 是渲染全部出去 # #fields = [‘id‘, ‘name‘] # [‘....‘] 是渲染指定的 # # exclude=[‘name‘] #是除了name 之外的全部都渲染出去,不能和fields同時出現 # #depth = 3 #深度 ,官方建議最多寫10,深度顯示所有的表 # #這裏是可以自定義,自定義顯示publish的名字, publish_name = serializers.CharField(source=‘publish.name‘) publish = serializers.SerializerMethodField() #也可以拿到publish的多個字段信息 def get_publish(self,obj): return {‘id‘:obj.publish.pk, ‘name‘:obj.publish.name} ###################這裏是serializers實例化實現方法二 的實現,調用ModelSerializer 最後建議使用serializers.ModelSerializer 來實現序列化 ,因為在修改接口和添加接口 對save() 有很好的依賴關系第二種序列化的方法(建議這種)
# 局部鉤子函數,對單個字段校驗 #校驗name字段不能以sb開頭 def validate_name(self,value): if value.startswith(‘sb‘): #不能讓你過 raise ValidationError(‘書名不能以sb開頭‘) else: return value #全局鉤子函數,對全局字段進行校驗 # def validate(self,a): # # print(a) # name=a.get(‘name‘) # price=a.get(‘price‘) # if name != price: # raise ValidationError(‘錯了‘) # else: # return a使用第二種後面還可以跟著寫局部鉤子和全局鉤子用於反序列化
最後視圖函數調用序列化的內容並返回給前端進行渲染處理
在View視圖層操作: 查詢多本書的方法: from rest_framework.views import APIView from rest_framework.response import Response from app.models import Book from app.Myserialize import Bookserializer class Books(APIView): # 這個是獲取多本書的接口 def get(self, request, *args, **kwargs): # 這裏是通過對drf框架 使用cbv 的get請求 response = {‘status‘: 100, ‘msg‘: ‘獲取成功‘} # 設置發送出去response 信息 book_list = Book.objects.all() book_ser = Bookserializer(book_list, many=True) # 使用drf 實例化 自定義的Bookserializer 來實例化 response[‘data‘] = book_ser.data # 把實例化book_ser 的data數據放入 response[‘data‘]中 return Response(response) # 在使用Response來返回出去 def post(self, request): #這個是添加書的接口 response = {‘status‘: 100, ‘msg‘: ‘添加成功‘} try: book_ser = Bookserializer(data=request.data) if book_ser.is_valid(): #這裏就是暈倒的反序列的內部工具和鉤子判斷 book_ser.save() response[‘data‘] = book_ser.data #判斷通過吧數據返回出去 else: response[‘msg‘] = book_ser.errors except Exception as e: response[‘msg‘] = str(e) return Response(response)簡單的調用序列化好的內容,並反饋給前端消息
class BookView(APIView): #獲取單本圖書的接口 def get(self, request, pk,*args, **kwargs): response = {‘status‘: 100, ‘msg‘: ‘獲取成功‘} #取到pk為傳入的pk的書,book對象 book = models.Book.objects.all().filter(pk=pk).first() #要序列化單條,many=False book_ser=BookSerializer(instance=book,many=False) # book_ser=BookSerializer(book,many=False) response[‘data‘]=book_ser.data return Response(response) def put(self,request,pk): #修改某本書 response = {‘status‘: 100, ‘msg‘: ‘修改‘} book=models.Book.objects.filter(pk=pk).first() #修改 book_ser = BookSerializer(instance=book,data=request.data) if book_ser.is_valid(): book_ser.save() response[‘data‘]=book_ser.data else: response[‘msg‘]=book_ser.errors return Response(response)接口顯示單個內容 ,主要PK是關鍵點
在路由層的配置: urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^books/$‘, views.BooksView.as_view()), #查看全部書的接口 url(r‘^books/(?P<pk>\d+)‘, views.BookView.as_view()), #查看單個書的接口 ]在urls 路由層進行判斷
#總結,個人建議使用第二種序列化的方法,這樣對反序列化有很好的幫助
以下是全部的接口信息 from app import models from app.Myserializers import BookSerializers # Create your views here. from rest_framework.views import APIView from rest_framework.response import Response class Booksview(APIView): def get(self,request,*args,**kwargs): #獲取多本書 response = {‘status‘:100, ‘msg‘:‘查詢成功‘} book_list = models.Book.objects.all() book_ser = BookSerializers(book_list,many=True) response[‘data‘] = book_ser.data return Response(response) def post(self,request): #添加書 response = {‘status‘:100, ‘msg‘:‘添加成功‘} try: book_ser = BookSerializers(data=request.data) #序列化工具拿到的數據是在request.data內的字典中獲取 if book_ser.is_valid(): #進行鉤子判斷與基礎驗證 book_ser.save() response[‘data‘] =book_ser.data else: response[‘msg‘]= book_ser.errors except Exception as e: response[‘msg‘] =str(e) return Response(response) class Bookview(APIView): def get(self, request, pk, *args, **kwargs): #獲取單本書的接口 response = {‘status‘:100 , ‘msg‘: ‘獲取成功‘} book = models.Book.objects.all().filter(pk=pk).first() book_ser = BookSerializers(instance=book,many=False) response[‘data‘] = book_ser.data return Response(response) def put(self, request,pk): #修改但本書的接口 response = {‘status‘:100, ‘msg‘:‘修改成功‘} book = models.Book.objects.filter(pk=pk).first() book_ser = BookSerializers(instance=book,data=request.data) if book_ser.is_valid(): book_ser.save() response[‘data‘]= book_ser.data else: response[‘msg‘]= book_ser.errors return Response(response) def delete(self,request,pk): #刪除的接口 response = {‘status‘:100, ‘msg‘: ‘刪除成功‘} book = models.Book.objects.filter(pk=pk).delete() return Response(response)以下是通過cbv實現的簡單的五種請求的接口實現方式
DRF框架之 serializers 序列化組件