drf序列化器的實例
阿新 • • 發佈:2019-03-20
rate 存在 efi gen 幫助 取數據 else 所有 sub
應用目錄結構:
views.py
from django.shortcuts import render # Create your views here. from django.views import View from django.http import JsonResponse, QueryDict from bookset.models import BookInfo #導入序列化列 from .serializers import BookInfoSerializer ##########################################################################################序列化########################################## class BookInfoView(View): def get(self,request): #1.操作數據庫 books=BookInfo.objects.all() #2.序列化 #創建序列化對象 #參數1:isntance.要序列化的模型數據 #參數2:data要反序列化的字典數據 #參數3:many,是否要序列化多個模型數據,多條數據many=True,默認為false #參數4:context=序列化的上下文.字典類型數據.可以通過context把視圖中的數據,傳遞給序列化器內部使用 serislizer=BookInfoSerializer(instance=books,many=True,) #通過serializer.data獲取序列化完成的數據 print(serislizer.data) #3.返回數據 return JsonResponse(serislizer.data,safe=False)####################################################### # 序列化器反序列化階段的使用 # 校驗數據和字典數據轉換成模型 #############################反序列化############################### from django.views import View from django.http import JsonResponse from .serializers import BookInfo2Serializer class BookInfo2View(View): def post(self,request): #添加一本書 #1.接收數據 data=request.POST #2.反序列化,驗證數據 #1.驗證數據 # 拋出異常 # is_valid調用驗證方式:字段選項validators->自定義驗證方法[單選項]->自定義驗證方法[多選項] # 驗證成功後的數據 serializer=BookInfo2Serializer(data=data) ret=serializer.is_valid(raise_exception=True) print(serializer.validated_data) # 轉換數據成模型.同步到數據庫中 # save會自動調用序列化器類裏面聲明的create/update方法,返回值是當前新增/更新的模型對象 serializer.save() #3.響應數據 print("====",serializer.data) #這邊響應的數據一定是序列化器反序列化後的數據,否則,異常不會返回給前端 return JsonResponse(serializer.data) def put(self,request,pk): ‘‘‘更新一個圖書‘‘‘ #根據主鍵獲取指定圖書信息 book=BookInfo.objects.get(pk=pk) #接受客戶端提交過來的數據 data=QueryDict(request.body) print(data) #使用序列化器完成驗證和反序列化的過程 #partial=True 接下來在反序列化中允許部分數據更新,針對字段選項必填的情況 serializer=BookInfo2Serializer(instance=book,data=data,partial=False) print("++++++++",serializer) ret=serializer.is_valid() print(ret) #save之所以可以自動識別,什麽時候執行create,什麽時候執行update, #主要按創建序列化器對象時候,是否有傳入instance #有instance參數,則save會調用序列化器中的update #沒有instance參數,則save會抵用序列化器內部的create serializer.save() return JsonResponse(serializer.data) ############################################## #3. 模型序列化器 # 1.可以幫助我們自動完成字聲明[主要從模型中的字段聲明裏面提取過來] # 2.模型序列化器要可以幫我們聲明create和update的方法和代碼 ############################################## from django.views import View from django.http import JsonResponse from .serializers import BookInfoModelSerializer class BookInfo3view(View): def post(self,request): ‘‘‘添加一本圖書‘‘‘ #接收數據 data=request.POST print(data) #反序列化 serializer=BookInfoModelSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data) def put(self,request,pk): ‘‘‘更新一本圖書‘‘‘ book=BookInfo.objects.get(pk=pk) #獲取數據 data=QueryDict(request.body) #反序列化 serializer=BookInfoModelSerializer(instance=book,data=data,partial=True) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data)
serializers.py(自己創建的,管理序列化器使用)
#!/usr/bin/env python # -*- coding: utf-8 -*- #author tom ################################################## # 序列化器之序列化 ################################################## from rest_framework import serializers from bookset.models import BookInfo class BookInfoSerializer(serializers.Serializer): #自定義要序列化反序列化的字段 id=serializers.IntegerField(label=‘主鍵id‘,read_only=True) btitle=serializers.CharField(label=‘圖書標題‘) bpub_date=serializers.DateField(label=‘出版日期‘) bread=serializers.IntegerField(label=‘閱讀量‘) bcomment=serializers.IntegerField(label=‘評論量‘) is_delete=serializers.BooleanField(label="邏輯刪除") ########################################################### # 2 序列化器的反序列化階段使用 # 主要用戶驗證數據和字典數據轉換成模型 ####################################################### from rest_framework import serializers # is_valid調用驗證方式:字段選項validators->自定義驗證方法[單選項]->自定義驗證方法[多選項] #自定義字段選選項函數(比較少用,一般用內置的) def check_btitle(data): if data==‘西廂記‘: raise serializers.ValidationError(‘西廂記也好黃啊‘) #一定要返回數據 return data class BookInfo2Serializer(serializers.Serializer): #自定義反序列化的字段 btitle = serializers.CharField(label=‘圖書標題‘,min_length=1,max_length=128,validators=[check_btitle]) bpub_date = serializers.DateField(label=‘出版日期‘) bread = serializers.IntegerField(label=‘閱讀量‘,min_value=0) bcomment = serializers.IntegerField(label=‘評論量‘,default=0) #表示當前字段可以不填 is_delete = serializers.BooleanField(label="邏輯刪除") #自定義驗證方法,單字段校驗[驗證單個字段,可以有多個方法] #格式:def validate_字段名(self,data):#data當前字段對應值 #data是形參,sub寫,代表的是當前字段對應的值 def validate_btitle(self,data): if data==‘紅樓夢‘: #拋出錯誤 raise serializers.ValidationError(‘紅樓夢太色請了‘) #校驗過後一定要把數據值返回,否則數據值為空 return data # 多字段校驗數據值data是所有字典的內容,字典類型 def validate(self,data): bread=data.get(‘bread‘) bcomment=data.get(‘bcomment‘) if bread>=bcomment: return data raise serializers.ValidationError(‘閱讀量小於評論量,太假了‘) def create(self,validated_data): ‘‘‘ view視圖的save會調用此方法 保存數據,把字典轉換成模型 :param validated_data: 客戶提交過來的,並且經過驗證的數據 :return: ‘‘‘ instance=BookInfo.objects.create( btitle=validated_data.get(‘btitle‘), bread=validated_data.get(‘bread‘), bcomment=validated_data.get(‘bcomment‘), bpub_date=validated_data.get(‘bpub_date‘), is_delete = validated_data.get(‘is_delete‘) ) return instance # def update(self,instance,validated_data): # ‘‘‘ # 更新數據 # instance 本次跟新操作的模型對象 # validated_data: 客戶提交過來,並經過驗證的數據 # :param instance: # :param validated_data: # :return: # ‘‘‘ # instance.btitle=validated_data.get("btitle"), # instance.bread = validated_data.get("bread"), # instance.bcomment = validated_data.get("bcomment"), # instance.bpub_date = validated_data.get("bpub_date"), # instance.is_delete = validated_data.get("is_delete"), # # #調用orm在操作 # instance.save() # #返回模型對象 # return instance def update(self,instance,validated_data): """更新數據 instance 本次更新操作的模型對象 validated_data 客戶端提交過來,並經過驗證的數據 """ instance.btitle=validated_data.get(‘btitle‘) instance.bread=validated_data.get(‘bread‘) instance.bcomment=validated_data.get(‘bcomment‘) instance.bpub_date=validated_data.get(‘bpub_date‘) instance.is_delete=validated_data.get(‘is_delete‘) # 調用ORM的保存更新操作 instance.save() # 返回模型對象 return instance ######################################################### #3. 模型序列化器 # 1.可以幫助我們自動完成字聲明[主要從模型中的字段聲明裏面提取過來] # 2.模型序列化器要可以幫我們聲明create和update的方法和代碼,所我們不需要自己寫crate和pub_date ######################################################### from rest_framework import serializers from bookset.models import BookInfo class BookInfoModelSerializer(serializers.ModelSerializer): #模型序列化器也可以自定義驗證字段(某些數據庫不存在,但是需要前端傳過來的,可以進行自定義) #例如:驗證碼,確認密碼 class Meta: model=BookInfo fields="__all__" #可以給模型序列 # 化器裏面指定的字段設置限制選項 extra_kwargs={ ‘bread‘:{"min_value":0,"required":True}, } # 自定義驗證方法[驗證單個字段,可以有多個方法] # def validate_<字段名>(self,data): # data當前字段對應的值 def validate_btitle(self, data): # 例如,圖書名不能是紅樓夢 if data == "紅樓夢": # 拋出錯誤 raise serializers.ValidationError("紅樓夢是禁書~") # 驗證方法中,把數據值必須返回給字段,否則字段值為空 return data # 自定義驗證方法[驗證多個或者所有字段,只能出現一次] def validate(self, data): # data 這個是所有字段的內容,字典類型 bread = data.get("bread") bcomment = data.get("bcomment") if bread >= bcomment: return data raise serializers.ValidationError("閱讀量小於評論量,數據太假了")
models.py
from django.db import models #定義圖書模型類BookInfo class BookInfo(models.Model): btitle = models.CharField(max_length=20, verbose_name=‘圖書標題‘) bpub_date = models.DateField(verbose_name=‘出版時間‘) bread = models.IntegerField(default=0, verbose_name=‘閱讀量‘) bcomment = models.IntegerField(default=0, verbose_name=‘評論量‘) is_delete = models.BooleanField(default=False, verbose_name=‘邏輯刪除‘) class Meta: db_table = ‘book‘ # 指明數據庫表名 verbose_name = ‘圖書‘ # 在admin站點中顯示的名稱 verbose_name_plural = verbose_name # 顯示的復數名稱 def __str__(self): """定義每個數據對象的顯示信息""" return "圖書:《"+self.btitle+"》" #定義英雄模型類HeroInfo class HeroInfo(models.Model): GENDER_CHOICES = ( (0, ‘female‘), (1, ‘male‘) ) hname = models.CharField(max_length=20, verbose_name=‘名稱‘) hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name=‘性別‘) hcomment = models.CharField(max_length=200, null=True, verbose_name=‘描述信息‘) hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name=‘圖書‘) # 外鍵 is_delete = models.BooleanField(default=False, verbose_name=‘邏輯刪除‘) class Meta: db_table = ‘heros‘ verbose_name = ‘英雄‘ verbose_name_plural = verbose_name def __str__(self): return self.hname
urls.py
#!/usr/bin/env python # -*- coding: utf-8 -*- #author tom from django.urls import path, re_path from .import views urlpatterns=[ path(‘books/‘,views.BookInfoView.as_view()), path("books2/",views.BookInfo2View.as_view()), re_path("books2/(?P<pk>\d+)/",views.BookInfo2View.as_view()), #model path("books3/",views.BookInfo3view.as_view()), re_path("books3/(?P<pk>\d+)/", views.BookInfo3view.as_view()) ]
主路由,項目路由:
urlpatterns = [ path(‘admin/‘, admin.site.urls), path(‘api/‘,include("bookset.urls")), #學習drf以後,編寫的最終版本 path("app/",include("app.urls")), path("ser/",include("ser.urls")) ]
drf序列化器的實例