序列化組件的三大功能 序列化,序列化器會把模型對象轉換成字典,經過response以後變成json字元串 反序列化,把客戶端發送過來的數據,經過request以後變成字典,序列化器可以把字典轉成模型 反序列化時同時會完成數據校驗功能 序列化器Serializer使用方法 查詢單個數據語法: 1.在s ...
序列化組件的三大功能
-
序列化,序列化器會把模型對象轉換成字典,經過response以後變成json字元串
-
反序列化,把客戶端發送過來的數據,經過request以後變成字典,序列化器可以把字典轉成模型
-
反序列化時同時會完成數據校驗功能
序列化器Serializer使用方法
查詢單個數據語法:
1.在setting.py中的app配置里註冊一下drf
2.在django的模型層創建一個表
from django.db import models
# Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
author = models.CharField(max_length=32)
3.在表中添加一些數據
4.編寫序列化組件(類似forms組件),可以在應用下單獨創一個文件夾,裡面放序列化組件.py
from rest_framework import serializers# 導入drf中的序列化類
# 創建一個類繼承Serializer序列化類
class BookSerializer(serializers.Serializer):
# 定義需要序列化的欄位,想要哪個欄位就添加該欄位,不需要就註釋掉
nid = serializers.CharField()
name = serializers.CharField()
price = serializers.CharField()
5.在url.py中開設路徑獲取序列化之後的數據
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^book/(?P<pk>\d+)/$',views.BooksView.as_view()) #CBV格式的url
]
6.在視圖函數中序列化需要的模型對象,返回給前端頁面字典格式的數據
from rest_framework.views import APIView # 導入drf模塊的apiview,使得cbv格式的視圖函數繼承它
from app01 import models
from .ser import BookSerializer # 導入自己寫好的序列化組件
from rest_framework.response import Response # 導入drf模塊的響應類
class BooksView(APIView):
# get請求的視圖函數
def get(self,request,pk):
# 得到需要查詢的模型對象
book = models.Book.objects.filter(pk=pk).first()
# 將模型對象交給自己寫好的序列化器,生成一個序列化對象
book_ser = BookSerializer(book)
# book_ser.data 序列化對象.data就是序列化後的字典
return Response(book_ser.data) # 利用drf中的Response類返回給前端,Response會幫您把這個字典序列化成json格式!
# 使用JsonResponse返回上述字典,在瀏覽器就沒有Response漂亮的格式而已,也是返回json數據格式
return JsonResponse(book_ser.data,json_dumps_params={'ensure_ascii':False})
查詢所有語法:
# views.py
class BooksView(APIView):
def get(self,request):
response_msg = {'status': 100, 'msg': '成功'}
books=Book.objects.all()
book_ser=BookSerializer(books,many=True) #序列化多條,如果序列化一條,不需要寫
response_msg['data']=book_ser.data
return Response(response_msg)
#urls.py
path('books/', views.BooksView.as_view()),
修改數據語法
1.在cbv格式的視圖函數中添加put函數
def put(self,request,pk):
back_dic = {'code':1000,'msg':'成功'}
# 1.得到需要查詢的模型對象
book = models.Book.objects.filter(pk=pk).first()
# 2. 將模型對象交給自己寫好的序列化器,生成一個序列化對象,除了傳模型對象,還需要傳入用戶修改的數據
book_ser = BookSerializer(instance=book,data=request.data)
# 3.進行數據校驗,類似forms組件的校驗
is_right = book_ser.is_valid()
if is_right:
# 4.校驗通過操作序列化對象保存修改數據
book_ser.save() # 註意這裡需要在序列化組件中重寫update()方法,否則報錯
# 5.將正確的數據在返回給前端
back_dic['data'] = book_ser.data
else:
back_dic['code'] = 1001
back_dic['msg'] = '數據格式不正確'
back_dic['data'] = book_ser.errors
return Response(back_dic)
2.在自定義的序列化組件類中添加update()方法
def update(self, instance, validated_data):
# instance參數就是book這個對象,validated_data就是用戶修改提交上來的字典格式數據
# 1.修改這個對象的欄位值
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
# 2.操作資料庫保存修改數據
instance.save() # 相當於book.save() 是django orm提供的方法
# 最後需要把這個book對象在返回出去
return instance
新增數據語法
# views.py
class BooksView(APIView):
# 新增
def post(self,request):
response_msg = {'status': 100, 'msg': '成功'}
#修改才有instance,新增沒有instance,只有data
book_ser = BookSerializer(data=request.data)
# book_ser = BookSerializer(request.data) # 這個按位置傳request.data會給instance,就報錯了
# 校驗欄位
if book_ser.is_valid():
book_ser.save()
response_msg['data']=book_ser.data
else:
response_msg['status']=102
response_msg['msg']='數據校驗失敗'
response_msg['data']=book_ser.errors
return Response(response_msg)
#ser.py 序列化類重寫create方法
def create(self, validated_data):
instance=Book.objects.create(**validated_data)
return instance
# urls.py
path('books/', views.BooksView.as_view()),
刪除數據語法:
# views.py
class BookView(APIView):
def delete(self,request,pk):
ret=Book.objects.filter(pk=pk).delete()
return Response({'status':100,'msg':'刪除成功'})
# urls.py
re_path('books/(?P<pk>\d+)', views.BookView.as_view()),
序列化的欄位類型
常用欄位類型
# BooleanField BooleanField()
# NullBooleanField NullBooleanField()
# CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
# EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
# RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
# SlugField SlugField(maxlength=50, min_length=None, allow_blank=False) 正則欄位,驗證正則模式 [a-zA-Z0-9-]+
# URLField URLField(max_length=200, min_length=None, allow_blank=False)
# UUIDField UUIDField(format=’hex_verbose’) format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
# IPAddressField IPAddressField(protocol=’both’, unpack_ipv4=False, **options)
# IntegerField IntegerField(max_value=None, min_value=None)
# FloatField FloatField(max_value=None, min_value=None)
# DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位數 decimal_palces: 小數點位置
# DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
# DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
# TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
# DurationField DurationField()
# ChoiceField ChoiceField(choices) choices與Django的用法相同
# MultipleChoiceField MultipleChoiceField(choices)
# FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
# ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
需要記住的欄位類型
CharField
BooleanField
IntegerField
DecimalField
ListField
DictField
常用的欄位參數
1 給CharField欄位類使用的參數
max_length 最長長度
min_length 最小長度
allow_blank 是否允許為空
trim_whitespace 是否截斷空白欄位
2 給IntegerField欄位類使用的參數
max_value 最小值
min_value 最大值
3 通用參數,放在哪個欄位類上都可以
required 表明該欄位在反序列化時必須輸入,預設True
default 反序列化時使用的預設值
allow_null 表明該欄位是否允許傳入None,預設False
validators 該欄位使用的驗證器
error_messages 包含錯誤編碼與錯誤信息的字典
label 用於HTML展示API頁面時,顯示的欄位名稱
help_text 用於Html展示API頁面時,顯示的欄位幫助提示信息
4 重點
read_only 表明該欄位僅用於序列化輸出,預設False,如果設置成True,postman中可以看到該欄位,修改時,不需要傳該欄位
write_only 表明該欄位僅用於反序列化輸入,預設False,如果設置成True,postman中看不到該欄位,修改時,該欄位需要傳
序列化組件中的鉤子函數和validators校驗
局部鉤子:
# 序列化組件中的鉤子函數
# 局部鉤子函數validate_欄位名的形式,需要傳入一個data參數,data就是price
def validate_price(self, data):
print(type(data)) #格式為<class 'str'>
print(data) # 34.00
# 進行校驗,當價格大於30報錯
if float(data) < 30:
return data
else:
# 校驗不通過,拋出異常 rest_framework異常在 from rest_framework.exceptions import ValidationError里
raise ValidationError('價格太高')
全局鉤子:
def validate(self,validated_data): # validated_data校驗之後的數據
name = validated_data.get('name')
price = validated_data.get('price')
if name == 'zhang' and price == '25':
raise ValidationError('不正確')
return validated_data
第三種validators校驗:
# 定義一個函數
def check_name(data):
if data.startswith('sb'):
raise ValidationError('名字不能是sb開頭')
else:
return data
# 在指定欄位內添加validators
name = serializers.CharField(validators=[check_name]) #validators=[]列表中寫函數的記憶體地址
總結:主要用局部鉤子和validators校驗,全局基本不用!!