前后端分離djangorestframework——序列化與反序列化數據


 

我們寫好后端的代碼,要把數據交給前端的展示的,這個數據以什么類型給前端呢?學到這里,我們已經知道這個數據最好是json字符串才行,因為網絡間的傳輸,只認字符串或者二進制,字符串就是我們的數據,二進制就是流媒體,比如圖片,視頻,音頻之類的

 

但是我們在后端經過邏輯處理得到的數據並不一定一開始就是個json字符串,所以就需要序列化下

 

補充:

  序列化:將其他類型的數據轉為字符串

  反序列化:將字符串轉回之前的數據類型(通常是字典類型)

  在Python中,可用於序列化與反序列化的就是json和pickle模塊,但是為了與restful規范相映,我們就用json模塊(因為前后端分離后,不能保證以后會做成更多的樣子,所以選用通用的json字符串)

 

 

創建一個django實例:

 我使用的是django2版本

 

建數據庫表:

from django.db import models

# 使用這個可以提前聲明表名,在使用外鍵約束時可以不用考慮表前后順序
__all__ = ['Book', 'Publisher', 'Author']


# Create your models here.

class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='圖書名稱')
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = models.IntegerField(choices=CHOICES, verbose_name='圖書類別')
    pub_time = models.DateField(verbose_name='出版時間')
    publisher = models.ForeignKey(to='Publisher', on_delete=None)
    author = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.title

    class Meta:
        # 自定義數據庫表名
        verbose_name_plural = 'book'
        db_table = verbose_name_plural


class Publisher(models.Model):
    title = models.CharField(max_length=32, verbose_name='出版社名稱')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = 'publish'
        db_table = verbose_name_plural


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name='作者名稱')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'author'
        db_table = verbose_name_plural

  

遷移數據庫后,添加數據:

出版社:

 

作者表:

 

圖書表:

 

 為app  demo1做路由分發,demo1下創建urls文件,基於CBV式(class-base-view,基於類的視圖)的指定url,當然你也可以使用FBV,基於函數的視圖函數,不過我建議你使用CBV的,后面你就會體會到了


 

定義視圖類對象:

 

 這里注意使用json的dumps時使用ensure_ascii為false,這樣在dump序列化時才不會只轉為ascii式的數據,導致一些字段不能被ascii表示

 

啟動django,訪問/list/:

這樣沒問題了對吧?

但是如果我取得字段有時間呢?我加一個pub_time字段:

class BookView(View):
    def get(self, request):
        book_list = models.Book.objects.values('id', 'title','pub_time')
        book_list = list(book_list)
        ret = json.dumps(book_list, ensure_ascii=False)
        return HttpResponse(ret)

  

再來訪問,報錯了

 

好的,這里就要用到 Jsonresponse

 

Jsonresponse

還是上面的代碼,用Jsonresponse返回:

 

 

里面加safe參數是因為我們從數據庫里取出來的是QuerySet類型,需要轉換成list更方便后面的處理。所以傳入safe,為什么傳入是因為它自己提示的如果是list則傳入safe

 

但是,由於我使用的pycharm,最開始是默認使用的django里帶的sqlite3,因為時間顯示會默認變成時間戳,在取出數據時會提示:Python int too large to convert to C long,意思就是int類型太長了,也就是說不能被識別為時間類型,所以我做了微調,把數據庫改成了mysql,添加的數據有點點不一樣,但是不影響

 

同樣的代碼,現在再訪問,可以了,但是還是有ascii碼的問題:

 

通過Jsonresponse的源碼可得,需要再傳入一個參數就行:

# coding:utf-8
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from django.views import View
import json
# Create your views here.
from demo1 import models


class BookView(View):
    def get(self, request):
        book_list = models.Book.objects.values("id", "title", 'pub_time')
        book_list = list(book_list)
        # ret = json.dumps(book_list, ensure_ascii=False)
        # print(book_list)
        return JsonResponse(book_list, safe=False, json_dumps_params={'ensure_ascii': False})

  

如果你打開還是亂碼的,你可以考慮換成谷歌瀏覽器

 
        

但是,又來了問題,如果要取出版社publisher字段呢? 圖書表中我們只是關聯了出版社,此時它就是一個id啊,如果我們要出版社的名字,所以需要再處理:

class BookView(View):
    def get(self, request):
        book_list = models.Book.objects.values("id", "title", 'pub_time','publisher')
        book_list = list(book_list)
        ret = []
        for field in book_list:
            pub_id = field['publisher']
            publish_obj = models.Publisher.objects.filter(id=pub_id).first()
            field['publisher'] = {
                'id':pub_id,
                'title':publish_obj.title
            }
            ret.append(field)

        return JsonResponse(ret, safe=False, json_dumps_params={'ensure_ascii': False})

  

 

 

數據是取出來了,但是你應該發現了一個問題,這個太不好維護了,在以后的開發中,肯定是數據很多,外鍵關聯也多,這樣一有一個外鍵關聯我們就要重新取處理一次,很麻煩對吧?而且還有choices字段,這個也要處理一下,反正以后遇到任何顯示不太符合習慣的都要做下處理,這樣是很費時間的,所以聰明的人想到了可以封裝一個類或者函數來處理,不過呢,有現成的,django已經給我們封好了一個serializers

 

django-serializers

 

代碼作適當處理:

# coding:utf-8
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from django.views import View
import json
# Create your views here.
from demo1 import models
from django.core import serializers

class BookView(View):
    def get(self,request):
        book_list = models.Book.objects.all()
        ret = serializers.serialize('json',book_list,ensure_ascii=False)
        return HttpResponse(ret)

 

訪問,很直接的就出來了:

但是還是有點小問題,比如category字段無法顯示等的,所以這個serializer相對JSONResponse只是好一點點,還是要再處理,則用DRF

 

DRF序列化(get)

 使用DRF那前提必須得裝djagnorestframework

 

下載完了之后,在django的配置文件settings.py里的app添加此app:

 

 接下來就可以使用rest_framework里的工具模塊了

 

新建一個py文件,名字隨意,這里我在demo1的app根目錄下新建一個serializers,定義如下的類,對應models表的字段

 

代碼:

from rest_framework import serializers


class PublishSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)


class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)


class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = serializers.ChoiceField(choices=CHOICES,source='get_category_display')
    pub_time = serializers.DateField()

    publisher = PublishSerializer()
    author = AuthorSerializer(many=True)
DRF序列化

 

 

視圖文件里:

 

代碼:

# coding:utf-8
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from django.views import View
import json
# Create your views here.
from demo1 import models
from django.core import serializers

from rest_framework.views import APIView
from rest_framework.response import Response
from demo1.serializers import BookSerializer


class BookView(APIView):
    def get(self, request):
        book_list = models.Book.objects.all()
        ret = BookSerializer(book_list, many=True)
        return Response(ret.data)
CBV

 

 注意視圖函數在序列化時用的many和在自定義序列化里用的many屬性,兩個注意區分,一個代表有多個字段值,一個代表多對多的外鍵約束

 

打開瀏覽器訪問:

 

這樣就很輕松的取出了相關的值,不需要我們自己再去手動處理了,很方便很實用,以后會經常用到這個序列化類

 

注:以上的web頁面是djangorestframework自己生成的,可以方便的做一些處理

 

既然有序列化,肯定也還有反序列化的

 

DRF反序列化(POST)

DRF的serializer不止可以序列化,當然還可以反序列化,這個就和django自己的form和modelform很類似了

 

對上面的序列化代碼進行微調:

序列化類:

 

代碼:

from rest_framework import serializers
from demo1 import models


class PublishSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)


class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)



class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=32)
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = serializers.ChoiceField(choices=CHOICES, source='get_category_display', read_only=True)

    w_category = serializers.ChoiceField(choices=CHOICES, write_only=True)
    pub_time = serializers.DateField()

    publisher = PublishSerializer(read_only=True)
    w_publish = serializers.IntegerField(write_only=True)
    author = AuthorSerializer(many=True, read_only=True)

    # 作者字段只需要傳入一個列表對象
    w_author = serializers.ListField(write_only=True)

    def create(self, validated_data):
        book_obj = models.Book.objects.create(title=validated_data['title'],
                                              category=validated_data['w_category'],
                                              pub_time=validated_data['pub_time'],
                                              publisher_id=validated_data['w_publish'])
        book_obj.author.add(*validated_data['w_author'])
        return book_obj
序列化類

 

視圖函數:

 

代碼:

# coding:utf-8
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from django.views import View
import json
# Create your views here.
from demo1 import models
from django.core import serializers

from rest_framework.views import APIView
from rest_framework.response import Response
from demo1.serializers import BookSerializer


class BookView(APIView):
    def get(self, request):
        book_list = models.Book.objects.all()
        ret = BookSerializer(book_list, many=True)
        return Response(ret.data)

    def post(self, request):
        # post的數據不再是在request.POST里
        # 而在request.data
        print(request.data)
        serialize = BookSerializer(data=request.data)
        if serialize.is_valid():
            # save是存儲
            serialize.save()
            return Response(serialize.validated_data)
        else:
            return Response(serialize.errors)
CBV

 

 當再視圖里定義了post之后,頁面則多了下面的插入框提交數據:

 

提交后返回結果:

 

 以上步驟就是反序列化

 

DRF的修改(put)

 

查看單條數據

 

url:

 

view:

 

訪問:

 

對單條數據修改

 

url不變

view,添加一個put方法

class BookEditView(APIView):
    def get(self, request, id):
        book_obj = models.Book.objects.filter(id=id).first()
        ret = BookSerializer(book_obj)
        return Response(ret.data)

    def put(self, request, id):
        book_obj = models.Book.objects.filter(id=id).first()
        # partial參數表示只對部分數據驗證
        serialize = BookSerializer(book_obj, data=request.data, partial=True)
        print(book_obj)

        if serialize.is_valid():
            # save是存儲
            serialize.save()
            return Response(serialize.validated_data)
        else:
            return Response(serialize.errors)

 

序列化器,添加一個update方法

 

from rest_framework import serializers
from demo1 import models


class PublishSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)


class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)


bookdata = {
    "title": "kali linux 入門到入獄",
    "w_category": 3,
    "pub_time": "2019-02-08",
    "w_publish": 2,
    "w_author": [1, 2, 4]
}


class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=32)
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = serializers.ChoiceField(choices=CHOICES, source='get_category_display', read_only=True)

    w_category = serializers.ChoiceField(choices=CHOICES, write_only=True)
    pub_time = serializers.DateField()

    publisher = PublishSerializer(read_only=True)
    w_publish = serializers.IntegerField(write_only=True)
    author = AuthorSerializer(many=True, read_only=True)

    # 作者字段只需要傳入一個列表對象
    w_author = serializers.ListField(write_only=True)

    def create(self, validated_data):
        book_obj = models.Book.objects.create(title=validated_data['title'],
                                              category=validated_data['w_category'],
                                              pub_time=validated_data['pub_time'],
                                              publisher_id=validated_data['w_publish'])
        book_obj.author.add(*validated_data['w_author'])
        return book_obj

    def update(self, instance, validated_data):
        # 次數的instance就是圖書表數據庫對象
        # 以下字段的key值也同樣必須使用上面的只寫的屬性key
        instance.title = validated_data.get('title',instance.title)
        instance.category = validated_data.get('w_category',instance.category)
        instance.pub_time = validated_data.get('pub_time',instance.pub_time)
        instance.publisher_id = validated_data.get('w_publish',instance.publisher_id)
        if validated_data.get('w_author'):
            instance.author.set(validated_data['w_author'])
        instance.save()
        return instance

 

 

注意以上的字段和前面的只讀或者只寫那些字段key值非常有關系,在修改時一定要一致

 

訪問頁面,並修改:

 

修改之前數據是這樣:

 

 

寫入以下修改,注意該怎么寫怎么寫,沒有空格縮進之類的,如果數據結尾了,也不要再加逗號分隔,結尾符之類的,不然報json的解析錯誤(我特么折騰了好半天才反應過來這里的問題):

 

 修改字段如下:

{
"title":"linux就該這么學第四版",
"pub_time":"2019-02-01",
"w_publish":1,
"w_author":[3]
}

 

提交得:

以上返回的結果由這一段代碼所得,即已驗證后的數據——validated_data

 

 

刷新:

 

 

注意:在使用rest_framework之后,如果有報錯,很多時候rest_framework會把這個報錯接管並顯示在前端頁面,后端頁面如果后端邏輯沒錯的話是不會顯示的,導致你根本無法分析錯誤原因。原因由這一段代碼而來:

 

都說DRF的serializer跟form以及modelform很像,那么自然也有鈎子函數驗證了

 

局部驗證鈎子

例:對title字段做局部驗證:

 

在序列化類添加一個局部鈎子方法即可:方法名為validate_XXX(XXX為序列化類定義過的字段名):

 

 

代碼:

class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=32)
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = serializers.ChoiceField(choices=CHOICES, source='get_category_display', read_only=True)

    w_category = serializers.ChoiceField(choices=CHOICES, write_only=True)
    pub_time = serializers.DateField()

    publisher = PublishSerializer(read_only=True)
    w_publish = serializers.IntegerField(write_only=True)
    author = AuthorSerializer(many=True, read_only=True)

    # 作者字段只需要傳入一個列表對象
    w_author = serializers.ListField(write_only=True)

    def create(self, validated_data):
        book_obj = models.Book.objects.create(title=validated_data['title'],
                                              category=validated_data['w_category'],
                                              pub_time=validated_data['pub_time'],
                                              publisher_id=validated_data['w_publish'])
        book_obj.author.add(*validated_data['w_author'])
        return book_obj

    def update(self, instance, validated_data):
        # 次數的instance就是圖書表數據庫對象
        # 以下字段的key值也同樣必須使用上面的只寫的屬性key
        instance.title = validated_data.get('title', instance.title)
        instance.category = validated_data.get('w_category', instance.category)
        instance.pub_time = validated_data.get('pub_time', instance.pub_time)
        instance.publisher_id = validated_data.get('w_publish', instance.publisher_id)
        if validated_data.get('w_author'):
            instance.author.set(validated_data['w_author'])
        instance.save()
        return instance

    def validate_title(self, value):
        if 'python' not in value.lower():
            raise serializers.ValidationError('修改失敗,內容必須包含python')
        return value
序列化類

 

 

訪問頁面修改測試:

點擊put得:

 

 完事兒了。有局部鈎子,自然也有全局鈎子

全局驗證鈎子

例:驗證修改的出版社和作者的id必須都為1,不然報錯:

 

 

代碼:

 

class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=32)
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = serializers.ChoiceField(choices=CHOICES, source='get_category_display', read_only=True)

    w_category = serializers.ChoiceField(choices=CHOICES, write_only=True)
    pub_time = serializers.DateField()

    publisher = PublishSerializer(read_only=True)
    w_publish = serializers.IntegerField(write_only=True)
    author = AuthorSerializer(many=True, read_only=True)

    # 作者字段只需要傳入一個列表對象
    w_author = serializers.ListField(write_only=True)

    def create(self, validated_data):
        book_obj = models.Book.objects.create(title=validated_data['title'],
                                              category=validated_data['w_category'],
                                              pub_time=validated_data['pub_time'],
                                              publisher_id=validated_data['w_publish'])
        book_obj.author.add(*validated_data['w_author'])
        return book_obj

    def update(self, instance, validated_data):
        # 次數的instance就是圖書表數據庫對象
        # 以下字段的key值也同樣必須使用上面的只寫的屬性key
        instance.title = validated_data.get('title', instance.title)
        instance.category = validated_data.get('w_category', instance.category)
        instance.pub_time = validated_data.get('pub_time', instance.pub_time)
        instance.publisher_id = validated_data.get('w_publish', instance.publisher_id)
        if validated_data.get('w_author'):
            instance.author.set(validated_data['w_author'])
        instance.save()
        return instance

    def validate_title(self, value):
        if 'python' not in value.lower():
            raise serializers.ValidationError('修改失敗,內容必須包含python')
        return value

    def validate(self, attrs):
        if attrs['w_publish'] == 1 and attrs['w_category'] == 1:
            return attrs
        else:
            raise serializers.ValidationError('分類和作者id必須一樣')
序列化類

 

 

訪問頁面提交測試:

 

 

 

提交得:

 

 

換成都為1的提交測試得:

 

自定義驗證鈎子

當然還可以自定義一個驗證鈎子:

 

 

 

代碼:

def my_validate(value):
    if '敏感信息' in value.lower():
        raise serializers.ValidationError('不能含有敏感信息')
    else:
        return value


class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=32, validators=[my_validate])
    CHOICES = ((1, 'python'), (2, 'GO'), (3, 'linux'))
    category = serializers.ChoiceField(choices=CHOICES, source='get_category_display', read_only=True)

    w_category = serializers.ChoiceField(choices=CHOICES, write_only=True)
    pub_time = serializers.DateField()

    publisher = PublishSerializer(read_only=True)
    w_publish = serializers.IntegerField(write_only=True)
    author = AuthorSerializer(many=True, read_only=True)

    # 作者字段只需要傳入一個列表對象
    w_author = serializers.ListField(write_only=True)

    def create(self, validated_data):
        book_obj = models.Book.objects.create(title=validated_data['title'],
                                              category=validated_data['w_category'],
                                              pub_time=validated_data['pub_time'],
                                              publisher_id=validated_data['w_publish'])
        book_obj.author.add(*validated_data['w_author'])
        return book_obj

    def update(self, instance, validated_data):
        # 次數的instance就是圖書表數據庫對象
        # 以下字段的key值也同樣必須使用上面的只寫的屬性key
        instance.title = validated_data.get('title', instance.title)
        instance.category = validated_data.get('w_category', instance.category)
        instance.pub_time = validated_data.get('pub_time', instance.pub_time)
        instance.publisher_id = validated_data.get('w_publish', instance.publisher_id)
        if validated_data.get('w_author'):
            instance.author.set(validated_data['w_author'])
        instance.save()
        return instance

    def validate_title(self, value):
        if 'python' not in value.lower():
            raise serializers.ValidationError('修改失敗,內容必須包含python')
        return value

    def validate(self, attrs):
        if attrs['w_publish'] == 1 and attrs['w_category'] == 1:
            return attrs
        else:
            raise serializers.ValidationError('出版社和作者id必須一樣')
序列化類

 

 

 

訪問修改測試:

 

由於我們自定義的驗證鈎子和局部驗證鈎子剛好都沒通過,都會報錯,但是只走了我們自定義的驗證鈎子,說明自定義驗證鈎子比默認的局部鈎子優先級高

 

 

總算問題都解決了,但是感覺還是不太好,我們就這么點功能,序列化類都寫了那么多一坨,怎么優化呢?

 

 

 

ModelSerializer序列化

其他都不用變,重新定義一個序列化類,把剛才繼承serializer類的自定義序列化類改了其他的名字,現在再定義一個繼承Modelserializer的序列化類,名為BookSerializer

 

代碼:

from rest_framework import serializers
from demo1 import models


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
        depth = 1  # 表示外鍵查找層級

 

 

訪問頁面:

 

 但是choices字段沒有顯示,做下稍微的調整

class BookSerializer(serializers.ModelSerializer):
    category = serializers.CharField(source="get_category_display") # 注意這里是CharField不是ChoicesField

    class Meta:
        model = models.Book
        fields = '__all__'
        depth = 1  # 表示外鍵查找層級

 

 

訪問頁面,已顯示choices字段:

 

顯示部分數據

由於上面的用的field = "__all__",所以默認會把所有字段顯示出來

部分顯示:

 

SerializerMethodField意思就是這個字段要通過方法獲取,下面的get_XXX是鈎子函數,使用了SerializerMethodField都得用鈎子函數來獲取,XXX字段名必須和定義的一致

訪問顯示,會靠前顯示我們自定義顯示的字段: 

 

 

ModelSerializer反序列化

 

那么我們要對其進行修改怎么辦呢,想比Serializer,簡單很多:

 

在既有read_only又有write_only時,記得把depth字段注釋掉,不然報錯,extra_kwargs表示只讀訪問時不顯示,在修改(只寫write_only)時才有效

 

代碼:

class BookSerializer(serializers.ModelSerializer):
    category_display = serializers.SerializerMethodField(read_only=True)
    authors = serializers.SerializerMethodField(read_only=True)
    publish_info = serializers.SerializerMethodField(read_only=True)

    def get_category_display(self, obj):
        return obj.get_category_display()

    def get_publish_info(self, obj):
        publish_obj = obj.publisher
        return {"id": publish_obj.id, 'title': publish_obj.title}

    def get_authors(self, obj):
        # obj是Book對象
        author_list = obj.author.all()
        return [{"id": author_obj.id, "name": author_obj.name} for author_obj in author_list]

    class Meta:
        model = models.Book
        fields = '__all__'
        # depth = 1  # 表示外鍵查找層級
        extra_kwargs = {
            "category": {"write_only": True},
            "publisher": {"write_only": True},
            "author": {"write_only": True},
        }
ModelSerializer

 

訪問查看:標注字段就是read_only時顯示的字段

 

 

 修改測試一下:

 

 

 

好的,完事兒

 

 

DRF的刪除

這個根本上其實與DRF無關,就用django字典的View也可以事先,不過還是在DRF下刪除下,增刪改查才齊了

 

沒有任何特別的,就在BookEditView視圖類里加了下面這段:

 

訪問測試:

這個自動生成的頁面就是這樣,你寫了一個不同的類型的請求方法就會多個請求的按鈕

點擊delete,刪除成功

 

然后再在整個視圖組件里稍微的改下,就是把那些增刪改操作正確時返回,就返回下正常的數據,而不是返回驗證通過的數據:

例:

 

代碼:

# coding:utf-8
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from django.views import View
import json
# Create your views here.
from demo1 import models
from django.core import serializers

from rest_framework.views import APIView
from rest_framework.response import Response
from demo1.serializers import BookSerializer



class BookView(APIView):
    def get(self, request):
        book_list = models.Book.objects.all()
        ret = BookSerializer(book_list, many=True)
        return Response(ret.data)

    def post(self, request):
        # post的數據不再是在request.POST里
        # 而在request.data
        print(request.data)
        serialize = BookSerializer(data=request.data)
        if serialize.is_valid():
            # save是存儲
            serialize.save()
            return Response(serialize.data)
        else:
            return Response(serialize.errors)


class BookEditView(APIView):
    def get(self, request, id):
        book_obj = models.Book.objects.filter(id=id).first()
        ret = BookSerializer(book_obj)
        return Response(ret.data)

    def put(self, request, id):
        book_obj = models.Book.objects.filter(id=id).first()
        # partial參數表示只對部分數據驗證
        serialize = BookSerializer(book_obj, data=request.data, partial=True)

        if serialize.is_valid():
            # print(serialize.validated_data)
            # save是存儲
            serialize.save()
            return Response(serialize.data)
        else:
            return Response(serialize.errors)

    def delete(self, request, id):
        book_obj = models.Book.objects.filter(id=id).exists()
        if not book_obj:
            return Response('不存在id為%s的數據,請重試' % id)
        else:
            models.Book.objects.filter(id=id).delete()
            return Response("刪除成功")
視圖CBV

 

 

 

序列化相關的還有很多,以上是主要的,更多的可以查看DRF的官方文檔:傳送門

 

 

好了,關於前后端分離,后端開發的序列化數據部分就到這 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM