序列化元件的校驗
阿新 • • 發佈:2018-12-18
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() ageView Code= 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__'
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