1. 程式人生 > >drf序列化器的實例

drf序列化器的實例

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序列化器的實例