1. 程式人生 > >序列化元件的校驗

序列化元件的校驗

1.簡介

校驗資料是否合法,有點類似forms元件。是校驗前臺傳過來的資料。

2.用法

在MySer中自定義校驗規則

可以控制某個欄位不傳,不進行校驗,但是進行這樣的設定後,當使用GET方法獲取資訊時,該欄位的顯示會受到影響。

注意:這個不傳的欄位,須是models表裡可以為空的欄位

authors=serializers.CharField(required=False)#設定該欄位可以不傳

當新建資料時,不需要傳pk的需求還好說,一旦需要傳pk值然後查詢相應book物件,然後進行更新相應的值時,這時就需要另配置路由了。另配置路由就是為了使用更加方便

注意,修改資料或者上傳資料增加物件時,可以多鍵值對,但是不能少資料。

Myser程式碼

from app01 import models
from rest_framework.serializers import Serializer, ModelSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError


class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField()
    age 
= serializers.CharField() # 配置連結的序列化 # class BookSerializer(serializers.Serializer): # name = serializers.CharField() # # view_name指的是配置的路由解析,lookup_field指的是查詢的欄位,lookup_url_kwarg指的是路由輸入的有名分組 # publish = serializers.HyperlinkedIdentityField(view_name='sss', lookup_field='publish_id',lookup_url_kwarg='pk')
class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' name = serializers.CharField(min_length=2, max_length=10, error_messages={'min_length': '最短為2', 'max_length': '最長為10', 'required': '這個必須填'}) # authors=serializers.CharField(required=False)#設定False後該欄位可以不傳 # 區域性鉤子 # 注意別寫錯函式 def validate_name(self, value):#name是name欄位 # value是通過了校驗的那個欄位的值 print(value) if value.startswith('sb'): # 不能以sb開頭 raise ValidationError('不能以煞筆開頭') else: return value #全域性鉤子 def validate(self, value): #value是所有校驗通過資料的字典 print(value) name=value.get('name') price=value.get('price') if str(name)==str(price): raise ValidationError('名字和價格不能相等') else: return value class PublishSerializer(serializers.ModelSerializer): class Meta: model = models.Publish fields = '__all__'
View Code

views程式碼

from django.shortcuts import render, HttpResponse, redirect, reverse
from django.http import JsonResponse
from app01 import models
from rest_framework.views import APIView
from app01 import MySer


# Create your views here.

class Book(APIView):
    def get(self, request, *args, **kwargs):
        books = models.Book.objects.all()
        # 這裡的context={'request':request}傳過去的request的變數是要拿到前面的連結,即ip或域名,不然無法生成新的連結
        book_ser = MySer.BookSerializer(books, many=True)
        # 返回的必須是book_ser.data
        return JsonResponse(book_ser.data, safe=False)

    def post(self, request, *args, **kwargs):
        # 前端傳過來的資料從data中取
        # 用序列化類的資料校驗
        # data引數,是要校驗的資料
        response = {'status': 100, 'msg': '成功'}
        ser = MySer.BookSerializer(data=request.data)
        # 這個校驗的過程,相當於前臺傳來資料,後臺去Book表,然後進行校驗資料,相當於查models裡建表時檢查各個欄位。
        if ser.is_valid():
            # 如果資料校驗通過,is_valid是True
            # 儲存到資料庫,相當於反序列化。也就相當於更新了book物件的資料
            # 注意:ser是MySer.BookSerializer的物件,其中BookSerializer必須是繼承了serializers.ModelSerializer,否則的話沒有和表的物件關係,不知道修改更新哪個表
            ser.save()
        else:
            response['status'] = 101
            response['msg'] = ser.errors
            print(type(ser.errors))
        return JsonResponse(response, safe=False)


class BooksDetail(APIView):
    def get(self, request, pk, *args, **kwargs):
        # 傳了pk值,有可能會有取不到的情況
        response = {'status': 100, 'msg': '成功'}
        book = models.Book.objects.filter(pk=pk).first()
        if book:
            book_ser = MySer.BookSerializer(book, many=False)
            response['data'] = book_ser.data
        else:
            response['status'] = 101
            response['msg'] = '您查詢的不存在'
        return JsonResponse(response, safe=False)

    def put(self, request, pk, *args, **kwargs):
        # 修改圖書資訊最好用put
        response = {'status': 100, 'msg': '修改成功'}
        book = models.Book.objects.filter(pk=pk).first()
        if book:
            #資料校驗
            #傳instance和不傳instance的區別
            #不傳instance,調save(),往資料庫新增資料
            #傳instance,調save(),往資料庫更新資料
            ser = MySer.BookSerializer(data=request.data, instance=book)
            if ser.is_valid():
                ser.save()
            else:
                response['status'] = 101
                response['msg'] = ser.errors
        else:
            response['status'] = 102
            response['msg'] = '修改的物件不存在'
        return JsonResponse(response, safe=False)


class Publish(APIView):
    def get(self, request, pk, *args, **kwargs):
        publish = models.Publish.objects.filter(pk=pk).first()
        publish_ser = MySer.PublishSerializer(publish, many=False)
        return JsonResponse(publish_ser.data, safe=False)
View Code