序列化,序列化器會(huì)把模型對(duì)象轉(zhuǎn)換成字典,經(jīng)過(guò)response以后變成json字符串
成都創(chuàng)新互聯(lián)公司專注于企業(yè)全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、資陽(yáng)網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5建站、電子商務(wù)商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為資陽(yáng)等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
反序列化,把客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),經(jīng)過(guò)request以后變成字典,序列化器可以把字典轉(zhuǎn)成模型
反序列化時(shí)同時(shí)會(huì)完成數(shù)據(jù)校驗(yàn)功能
1.在setting.py中的app配置里注冊(cè)一下drf
2.在django的模型層創(chuàng)建一個(gè)表
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.在表中添加一些數(shù)據(jù)
4.編寫序列化組件(類似forms組件),可以在應(yīng)用下單獨(dú)創(chuàng)一個(gè)文件夾,里面放序列化組件.py
from rest_framework import serializers# 導(dǎo)入drf中的序列化類
# 創(chuàng)建一個(gè)類繼承Serializer序列化類
class BookSerializer(serializers.Serializer):
# 定義需要序列化的字段,想要哪個(gè)字段就添加該字段,不需要就注釋掉
nid = serializers.CharField()
name = serializers.CharField()
price = serializers.CharField()
5.在url.py中開(kāi)設(shè)路徑獲取序列化之后的數(shù)據(jù)
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^book/(?P<pk>\d+)/$',views.BooksView.as_view()) #CBV格式的url
]
6.在視圖函數(shù)中序列化需要的模型對(duì)象,返回給前端頁(yè)面字典格式的數(shù)據(jù)
from rest_framework.views import APIView # 導(dǎo)入drf模塊的apiview,使得cbv格式的視圖函數(shù)繼承它
from app01 import models
from .ser import BookSerializer # 導(dǎo)入自己寫好的序列化組件
from rest_framework.response import Response # 導(dǎo)入drf模塊的響應(yīng)類
class BooksView(APIView):
# get請(qǐng)求的視圖函數(shù)
def get(self,request,pk):
# 得到需要查詢的模型對(duì)象
book = models.Book.objects.filter(pk=pk).first()
# 將模型對(duì)象交給自己寫好的序列化器,生成一個(gè)序列化對(duì)象
book_ser = BookSerializer(book)
# book_ser.data 序列化對(duì)象.data就是序列化后的字典
return Response(book_ser.data) # 利用drf中的Response類返回給前端,Response會(huì)幫您把這個(gè)字典序列化成json格式!
# 使用JsonResponse返回上述字典,在瀏覽器就沒(méi)有Response漂亮的格式而已,也是返回json數(shù)據(jù)格式
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格式的視圖函數(shù)中添加put函數(shù)
def put(self,request,pk):
back_dic = {'code':1000,'msg':'成功'}
# 1.得到需要查詢的模型對(duì)象
book = models.Book.objects.filter(pk=pk).first()
# 2. 將模型對(duì)象交給自己寫好的序列化器,生成一個(gè)序列化對(duì)象,除了傳模型對(duì)象,還需要傳入用戶修改的數(shù)據(jù)
book_ser = BookSerializer(instance=book,data=request.data)
# 3.進(jìn)行數(shù)據(jù)校驗(yàn),類似forms組件的校驗(yàn)
is_right = book_ser.is_valid()
if is_right:
# 4.校驗(yàn)通過(guò)操作序列化對(duì)象保存修改數(shù)據(jù)
book_ser.save() # 注意這里需要在序列化組件中重寫update()方法,否則報(bào)錯(cuò)
# 5.將正確的數(shù)據(jù)在返回給前端
back_dic['data'] = book_ser.data
else:
back_dic['code'] = 1001
back_dic['msg'] = '數(shù)據(jù)格式不正確'
back_dic['data'] = book_ser.errors
return Response(back_dic)
2.在自定義的序列化組件類中添加update()方法
def update(self, instance, validated_data):
# instance參數(shù)就是book這個(gè)對(duì)象,validated_data就是用戶修改提交上來(lái)的字典格式數(shù)據(jù)
# 1.修改這個(gè)對(duì)象的字段值
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
# 2.操作數(shù)據(jù)庫(kù)保存修改數(shù)據(jù)
instance.save() # 相當(dāng)于book.save() 是django orm提供的方法
# 最后需要把這個(gè)book對(duì)象在返回出去
return instance
# views.py
class BooksView(APIView):
# 新增
def post(self,request):
response_msg = {'status': 100, 'msg': '成功'}
#修改才有instance,新增沒(méi)有instance,只有data
book_ser = BookSerializer(data=request.data)
# book_ser = BookSerializer(request.data) # 這個(gè)按位置傳request.data會(huì)給instance,就報(bào)錯(cuò)了
# 校驗(yàn)字段
if book_ser.is_valid():
book_ser.save()
response_msg['data']=book_ser.data
else:
response_msg['status']=102
response_msg['msg']='數(shù)據(jù)校驗(yàn)失敗'
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) 正則字段,驗(yàn)證正則模式 [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-fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee0fb31a" 3)'int' - 如: "" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-fb31a"
# 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: 最多位數(shù) decimal_palces: 小數(shù)點(diǎn)位置
# 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
常用的字段參數(shù)
1 給CharField字段類使用的參數(shù)
max_length 最長(zhǎng)長(zhǎng)度
min_length 最小長(zhǎng)度
allow_blank 是否允許為空
trim_whitespace 是否截?cái)嗫瞻鬃侄?
2 給IntegerField字段類使用的參數(shù)
max_value 最小值
min_value 最大值
3 通用參數(shù),放在哪個(gè)字段類上都可以
required 表明該字段在反序列化時(shí)必須輸入,默認(rèn)True
default 反序列化時(shí)使用的默認(rèn)值
allow_null 表明該字段是否允許傳入None,默認(rèn)False
validators 該字段使用的驗(yàn)證器
error_messages 包含錯(cuò)誤編碼與錯(cuò)誤信息的字典
label 用于HTML展示API頁(yè)面時(shí),顯示的字段名稱
help_text 用于Html展示API頁(yè)面時(shí),顯示的字段幫助提示信息
4 重點(diǎn)
read_only 表明該字段僅用于序列化輸出,默認(rèn)False,如果設(shè)置成True,postman中可以看到該字段,修改時(shí),不需要傳該字段
write_only 表明該字段僅用于反序列化輸入,默認(rèn)False,如果設(shè)置成True,postman中看不到該字段,修改時(shí),該字段需要傳
局部鉤子:
# 序列化組件中的鉤子函數(shù)
# 局部鉤子函數(shù)validate_字段名的形式,需要傳入一個(gè)data參數(shù),data就是price
def validate_price(self, data):
print(type(data)) #格式為<class 'str'>
print(data) # 34.00
# 進(jìn)行校驗(yàn),當(dāng)價(jià)格大于30報(bào)錯(cuò)
if float(data) < 30:
return data
else:
# 校驗(yàn)不通過(guò),拋出異常 rest_framework異常在 from rest_framework.exceptions import ValidationError里
raise ValidationError('價(jià)格太高')
全局鉤子:
def validate(self,validated_data): # validated_data校驗(yàn)之后的數(shù)據(jù)
name = validated_data.get('name')
price = validated_data.get('price')
if name == 'zhang' and price == '25':
raise ValidationError('不正確')
return validated_data
第三種validators校驗(yàn):
# 定義一個(gè)函數(shù)
def check_name(data):
if data.startswith('sb'):
raise ValidationError('名字不能是sb開(kāi)頭')
else:
return data
# 在指定字段內(nèi)添加validators
name = serializers.CharField(validators=[check_name]) #validators=[]列表中寫函數(shù)的內(nèi)存地址
總結(jié):主要用局部鉤子和全局鉤子??!
# 模型化序列器,繼承ModelSerializer,并且不需要自己書寫updata和create方法了
class BookSerializer2(serializers.ModelSerializer):
# 1.定義一個(gè)Meta類
class Meta:
# 2.model后面等于需要序列化的表
model = models.Book
# 3.表示序列化該表中所有的字段
# fields = '__all__'
# 4.序列化表中的指定字段
# fields = ('name','price') # 注意fields里可以放model.py里book表對(duì)應(yīng)的字段,也可以放book表類里定義的方法(詳解下圖)
# 5.序列化除以下字段
exclude = ('name',) # ()里是一個(gè)元組,注意需要加個(gè)逗號(hào)
# 6.read_only和write_only這些原本需要在字段括號(hào)內(nèi)書寫的參數(shù)都放在extra_kwargs里書寫
extra_kwargs = {
'price':{'write_only':True},
}
在book表類里加的publish_name方法,fields里放該方法,會(huì)返回該方法的返回值!
視圖函數(shù)部分:
class BooksView2(APIView):
def get(self,request):
books = models.Book.objects.all()
book_ser = BookSerializer2(books,many=True) # 這里改成了BookSerializer2模型化序列器
return Response(book_ser.data)
class MyResponse(): # 這里復(fù)雜一點(diǎn)可以繼承rest_framework的Response類
def __init__(self): # 定義一個(gè)初始化方法,該方法有默認(rèn)屬性status和msg(任何由該類產(chǎn)生的對(duì)象都有這兩個(gè)屬性)
self.status=100
self.msg = '成功'
@property # 將這個(gè)方法偽裝成屬性
def get_dict(self):
return self.__dict__ # 返回一個(gè)字典
新聞名稱:序列化組件
文章網(wǎng)址:http://redsoil1982.com.cn/article38/dsogcsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、微信公眾號(hào)、靜態(tài)網(wǎng)站、網(wǎng)站收錄、網(wǎng)站設(shè)計(jì)公司、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)