1. 程式人生 > >【DRF框架】利用序列化元件操作

【DRF框架】利用序列化元件操作

使用序列化元件進行操作

不帶引數:查+增

帶引數:查、改、刪

 

不帶引數的操作

# url路由
url(r'^book_list/$',Search_book.as_view()),
# views.py
from utils.serializers import BookSerializer
from .models import Book
from rest_framework.response import Response
from rest_framework.views import APIView


class Search_book(APIView):
    
# 查詢資料,GET請求 def get(self,request): book_queryset = Book.objects.all() # 使用序列化器進行序列化,返回序列化物件 ser_obj = BookSerializer(book_queryset,many=True) # 多個queryset物件使用many=True # 返回資料 return Response(ser_obj.data) # 序列化好的資料都在 序列化物件.data # 新增資料,POST請求
def post(self,request): # 對提交的資料進行反序列化,返回一個序列化物件 ser_obj = BookSerializer(data=request.data) # 對序列化物件進行校驗 if ser_obj.is_valid(): # 校驗通過,新增資料 ser_obj.save() # 呼叫序列化器的create()方法 return Response(ser_obj.data) # 返回新增的資料 else
: # 校驗不通過 return Response(ser_obj.errors)
# 序列化器
# serializers.py
from rest_framework import serializers   # 匯入框架的序列化器
from SerDemo.models import Book


# 外來鍵欄位的序列化器
class PublisherSerializer(serializers.Serializer):
    # 根據外來鍵模型的欄位定義欄位進行匹配
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)

# 多對多欄位的序列化器
class AuthorSerializer(serializers.Serializer):
    # 根據多對多欄位模型的欄位定義欄位進行匹配
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)

# 自定義驗證器
def my_validate(value):
    if "xxx" in value:
        raise serializers.ValidationError("該欄位包含敏感詞!!!")
    else:
        return value

class BookSerializer(serializers.Serializer):
    # 定義模型中需要序列化的欄位,匹配的上的進行序列化,匹配不上的丟棄
    id = serializers.IntegerField(required=False)           # 反序列化不匹配該欄位
    title = serializers.CharField(max_length=32,validators=[my_validate,])             # 使用自定義驗證器
    category = serializers.CharField(source='get_category_display',read_only=True)     # source通過ORM操作獲得CHOICES的值
    category_post = serializers.IntegerField(write_only=True)                          # 用於反序列化的欄位
    pub_time = serializers.DateField()

    # 外來鍵欄位,先宣告外來鍵欄位的序列化器再例項化
    publisher = PublisherSerializer(read_only=True)             # 僅在正序列化匹配該欄位
    publisher_id = serializers.IntegerField(write_only=True)    # 僅在反序列化匹配該欄位

    # 多對多欄位,先宣告多對多欄位的序列化器再例項化
    authors = AuthorSerializer(read_only=True,many=True)       # 多個模型物件使用many=True,正序列化匹配該欄位
    authors_list = serializers.ListField(write_only=True)      # 反序列化匹配該欄位



    # 新增物件呼叫create方法
    def create(self, validated_data):
        # validated_data 是資料的字典

        # 建立物件
        book_obj = Book.objects.create(
            title=validated_data.get('title'),
            category=validated_data.get('category_post'),
            pub_time = validated_data.get('pub_time'),
            publisher_id = validated_data.get('publisher_id'),
        )
        book_obj.authors.add(*validated_data['authors_list'])       # 多對多欄位使用add
        book_obj.save()
        return book_obj

 

帶引數的操作

# url路由
url(r'^book_list/(?P<id>\d+)/$',EditBookView.as_view())
from django.shortcuts import render

from utils.serializers import BookSerializer
from .models import Book
from rest_framework.response import Response
from rest_framework.views import APIView

# 帶id的查詢、更新、刪除
class EditBookView(APIView):
    # 根據id檢視資料
    def get(self,request,id):
        # 根據ip找到模型物件
        book_obj = Book.objects.filter(pk=id).first()

        # 對模型物件進行序列化,返回序列化物件
        ser_obj = BookSerializer(book_obj)

        # 返回序列化物件的資料
        return Response(ser_obj.data)

    # 根據id更新資料
    def put(self,request,id):
        # 根據ip找到模型物件
        book_obj = Book.objects.filter(pk=id).first()

        # 將獲取的資料根據模型物件進行序列化,返回序列化物件
        ser_obj = BookSerializer(instance=book_obj,data=request.data,partial=True)
        # partial=True 部分匹配
        # data=request.data 前端提交的資料
        # instance=book_obj根據id找到的例項化物件

        # 對例項化物件進行校驗
        if ser_obj.is_valid():
            # 校驗通過,呼叫save進行更新
            ser_obj.save()      # 內部呼叫序列化器的update方法
            return Response(ser_obj.data)
        else:
            return Response(ser_obj.errors)     # 返回錯誤資訊

    # 根據id刪除資料
    def delete(self,request,id):
        # 根據ip找到模型物件
        book_obj = Book.objects.filter(pk=id).first()

        if book_obj:
            book_obj.delete()
            return Response("刪除成功")
        else:
            return Response("刪除失敗")
# serializers.py
from rest_framework import serializers   # 匯入框架的序列化器
from SerDemo.models import Book


# 外來鍵欄位的序列化器
class PublisherSerializer(serializers.Serializer):
    # 根據外來鍵模型的欄位定義欄位進行匹配
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)

# 多對多欄位的序列化器
class AuthorSerializer(serializers.Serializer):
    # 根據多對多欄位模型的欄位定義欄位進行匹配
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)

# 自定義驗證器
def my_validate(value):
    if "xxx" in value:
        raise serializers.ValidationError("該欄位包含敏感詞!!!")
    else:
        return value

class BookSerializer(serializers.Serializer):
    # 定義模型中需要序列化的欄位,匹配的上的進行序列化,匹配不上的丟棄
    id = serializers.IntegerField(required=False)           # 反序列化不匹配該欄位
    title = serializers.CharField(max_length=32,validators=[my_validate,])             # 使用自定義驗證器
    category = serializers.CharField(source='get_category_display',read_only=True)     # source通過ORM操作獲得CHOICES的值
    category_post = serializers.IntegerField(write_only=True)                          # 用於反序列化的欄位
    pub_time = serializers.DateField()

    # 外來鍵欄位,先宣告外來鍵欄位的序列化器再例項化
    publisher = PublisherSerializer(read_only=True)             # 僅在正序列化匹配該欄位
    publisher_id = serializers.IntegerField(write_only=True)    # 僅在反序列化匹配該欄位

    # 多對多欄位,先宣告多對多欄位的序列化器再例項化
    authors = AuthorSerializer(read_only=True,many=True)       # 多個模型物件使用many=True,正序列化匹配該欄位
    authors_list = serializers.ListField(write_only=True)      # 反序列化匹配該欄位


    # 更新物件呼叫update()方法
    def update(self, instance, validated_data):
        # instance就是傳入的模型物件
        # validated_data就是序列化的資料組成的字典

        # 如果更新的資料存在多對多的欄位,就呼叫set方法
        if validated_data.get('authors_list',None):
            instance.authors.set(validated_data['authors_list'])


        # 根據欄位取值,取不到就用物件的值
        instance.title=validated_data.get('title',instance.title)
        instance.save()

        # 返回物件
        return instance