1. 程式人生 > 其它 >簡單的drf操作流程式列化操作

簡單的drf操作流程式列化操作

前提資料庫中資料已經搭建完畢

簡單使用:
1.寫一個序列化的類MySer,繼承Serializer

2.在該類中寫出所要序列化的欄位,欄位名相同即可 不同的話可以利用 source引數來引出

3.在檢視類中的使用 將資料物件傳入即可 book_ser = MySer(instance=book) 最後返回book_ser.data即可

一般來講 可以先定義一個字典 裡面攜帶msg code data等引數如下

back_dic = {'code':100,'msg':'成功'}

預設成功 如果成功 給back_dic['data'] = 'book_ser.data'

返回字典即可

如果失敗back_dic['data'] = 'book_ser.error' 並且修改 code 和 msg引數

from rest_frameword import serializers


class MySer(serializers.Serilaizer):
    title1 = serializers.CharField(source='title')
    price = serializers.CharField(max_length=16,min_length=4)
    pub_date = serializers.CharField(source='test')
    publish = serializers.CharField(source='publish.email
') # authors = serializers.CharField() authors = serializers.SerializerMethodField()

注意上述括號內可以攜帶限制引數 ,並且同時也會有類似區域性鉤子函式和全域性鉤子函式的使用 其中 括號內的vali'da'tors=[check_author] xxx可以是一個函式地址 例如可以限定作者名字開頭不能sb等字元、

def check_author(data):
if data.startswith('sb'):
raise ValidationError("名字帶有歧義請重新修改")
else:
return data
    def validate_price(self, data):  # 區域性鉤子函式 data就是validate後面的值也就是price
        if float(data) > 10:
            return data
        else:
            raise ValidationError("價格太低")

    def validate(self, attrs):  # attrs是request.data裡所傳的資料 也就是資料庫中的資料 類似於全域性鉤子函式
        print(attrs)
        author = attrs.get('author')
        publish = attrs.get('publish')
        if author == publish:
            raise ValidationError("作者與出版社重複")
        else:
            return attrs

對於資料增加和修改 其中所用到的儲存 需要在序列化類中重新定義update和create函式

    def post(self,request):#新增資料
        back_dic = {'code': 1000, 'msg': '成功'}
        #新增沒有instance物件
        book_ser = ser.BookSerializer(data = request.data)
        #book_ser = ser.BookSerializer(request.data)這樣寫相當將request.data賦值給instance會報錯 所以要指出賦值給誰
        if book_ser.is_valid():
            book_ser.save()
            back_dic['data'] = book_ser.data
        else:
            back_dic['code'] = 1001
            back_dic['msg'] = "欄位校驗失敗"
            back_dic['data'] = book_ser.errors
        return Response(back_dic)
  
    def put(self,request,pk): #修改資料注意pk引數的傳入 規定了我要改哪條資料
        back_dic = {'code':1000,'msg':'成功'}
        book = models.Book.objects.filter(pk=pk).first()
        #book_ser = ser.BookSerializer(book,request.data)
        book_ser = ser.BookSerializer(instance=book,data=request.data)
        #要資料驗證
        if book_ser.is_valid():
            book_ser.save()  #報錯  序列化器的儲存方法 需要重寫update方法
            back_dic['data'] = book_ser.data
        else:
            back_dic['code'] = 1001
            back_dic['msg'] = "失敗"
            back_dic['data'] = book_ser.errors
        return Response(back_dic)
#重寫update和create方法在序列化類中
    def update(self, instance, validated_data):
        # instance是book這個物件
        # validated_data是校驗後的資料
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.author = validated_data.get('author')
        instance.publish = validated_data.get('publish')
        instance.save()  # book.save() 是django ormtigo1的
        return instance

    def create(self, validated_data):
       instance = models.Book.objects.create(**validated_data)#打散剛好是所要建立的各種引數
        #models.Book.objects.create(name=validated_data.get['name'],price=validated_data.get['price']....)
       return instance

  

ModelSerializer的使用Serializer基本相似 略微不同 不需要重寫update和create方法
建立序列化類時如下
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
        # fields = ('name','price') #只看name和price欄位
        # exclude = ['price','author'] #後面必須是列表
        # read_only_fields = ['price']
        #write_only_fields = ['price']#該欄位被棄用了
        extra_kwargs = {#類似於name = serializers.CharField(max_length=16, min_length=4) 括號裡所攜帶的引數
            'id':{'write_only':True,'read_only':False},
        }

對於輸出authors欄位時直接是無法展示全面的資訊 所以要進行以下操作

authors = serializers.SerializerMethodField()
    def get_authors(self,instance): #即book物件
        authors = instance.authors.all()
        ll = []
        for author in authors:
            ll.append({'name':author.name,'age':author.age})

        return ll #return什麼東西 就取到什麼東西

同時需要記住的是 source引數的使用