序列化器的使用分為兩個(gè)階段:
1、創(chuàng)建一個(gè)表模型
from django.db import models class Books(models.Model): title = models.CharField(verbose_name='書名', max_length=32) publish = models.CharField(verbose_name='出版社', max_length=32) price = models.DecimalField(verbose_name='價(jià)格', max_digits=5, decimal_places=2)
2、新建一個(gè)py文件,寫一個(gè)序列化的類,繼承Serializer
3、在類中寫要序列化的字段,想序列化那個(gè)字段,就在類中寫那個(gè)字段
from rest_framework import serializers class BooksSerializer(serializers.Serializer): title = serializers.CharField() publish = serializers.CharField() price = serializers.DecimalField()
4、在視圖類中使用,導(dǎo)入——》實(shí)例化得到序列化對(duì)象,把要序列化的對(duì)象傳入
5、序列化的對(duì)象.data——》是一個(gè)字典
6、把字典返回,如果不使用rest_framework提供的Response,就得使用JsonResponse
from rest_framework.views import APIView from rest_framework.request import Request from app01.models import Books from app01.ser import BooksSerializer class BookView(APIView): def get(self, request, pk): # 響應(yīng)信息 response_msg = {'status': 200, 'message': '查詢成功'} # 獲取要序列化的對(duì)象 book = Books.objects.filter(pk=pk).first() # 要序列化誰(shuí)就把誰(shuí)傳到序列化類去 book_ser = BooksSerializer(book) # book_ser.data————》序列化對(duì)象.data————》就是序列化后的字典 # 將查詢結(jié)果添加到響應(yīng)信息內(nèi) response_msg['data'] = book_ser.data return Response(response_msg) # urls.py re_path(r'^book/(?Ppk>\d+)/', views.BookView.as_view()),
7、如果要被序列化的是包含多條數(shù)據(jù)的查詢集queryset,可以通過(guò)添加many=True參數(shù)
from rest_framework.views import APIView from rest_framework.response import Response from app01.models import Books from app01.ser import BooksSerializer class BooksView(APIView): def get(self, request): # 響應(yīng)信息 response_msg = {'status': 200, 'message': '查詢成功'} books = Books.objects.all() # 要序列化誰(shuí)就把誰(shuí)傳到序列化類去 book_ser = BooksSerializer(books, many=True) # book_ser.data————》序列化對(duì)象.data————》就是序列化后的字典 # 將查詢結(jié)果添加到響應(yīng)信息內(nèi) response_msg['data'] = book_ser.data return Response(response_msg) # urls.py re_path(r'^books/', views.BookView.as_view()),
1、可以修改字段名字
class BooksSerializer(serializers.Serializer): xxx = serializers.CharField(source='title') # 相當(dāng)于——》xxx = Books.title # 響應(yīng) { "status": 200, "message": "查詢成功", "data": { "xxx": "魔道祖師" ————》響應(yīng)的字段名被修改了 } }
2、可以跨表查詢
class BookSerializer(serializers.Serializer): publish_email = serializers.CharField(source='publish.email') # 相當(dāng)于——》publish_email = Book.publish.email 連表查詢publish表的email字段 # 響應(yīng) { "status": 200, "message": "查詢成功", "data": { "publish_email": "modao@163.com" } }
3、可以執(zhí)行方法
# models.py class Book(models.Model): title = models.CharField(max_length=32) price = models.IntegerField() pub_date = models.DateTimeField() publish = models.ForeignKey("Publish", on_delete=models.CASCADE, null=True) authors = models.ManyToManyField("Author") def func(self): return '666666' # ser.py class BookSerializer(serializers.Serializer): msg = serializers.CharField(source='func') # msg = Book.func ——》調(diào)用Book類中的func()方法的返回值 # 響應(yīng) { "status": 200, "message": "查詢成功", "data": { "msg": "666666" } }
它需要有一個(gè)配套的方法,方法名叫做get_字段名,返回值就是要顯示的東西
class BookSerializer(serializers.Serializer): authors = serializers.SerializerMethodField() def get_authors(self, instance): # instance ——》 Book對(duì)象 authors = instance.authors.all() # 取出所有作者 author_list = [] for author in authors: author_list.append({'name': author.name, 'age': author.age}) return author_list
read_only:(只讀)表明該字段僅用于序列化輸出,默認(rèn)False,如果設(shè)置成True,響應(yīng)中可以看到該字段,修改時(shí),不需要傳該字段
write_only:(只寫)表明該字段僅用于反序列化輸入,默認(rèn)False,如果設(shè)置成True,響應(yīng)中看不到該字段,修改時(shí),該字段需要傳
from rest_framework import serializers class BooksSerializer(serializers.Serializer): title = serializers.CharField(read_only = True) # 響應(yīng)中能看到改字段,修改不需要傳值 publish = serializers.CharField(write_only = True) # 響應(yīng)中看不到改字段,修改需要傳值 price = serializers.DecimalField()
還有參數(shù)如下:
當(dāng)使用序列化器對(duì)數(shù)據(jù)進(jìn)行反序列化時(shí),就需要對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)了,只有校驗(yàn)成功的數(shù)據(jù)才能被保存成模型類對(duì)象
將要校驗(yàn)的數(shù)據(jù)傳入序列化器中并實(shí)例化:obj = BooksSerializer(data=request.data),調(diào)用is_valid()方法校驗(yàn),校驗(yàn)成功返回True,失敗返回False。
失敗,可以通過(guò)序列化器對(duì)象的errors獲取錯(cuò)誤信息(字典)
成功,可以公共序列化對(duì)象的validated_data屬性獲取數(shù)據(jù)。
校驗(yàn)方法有:局部鉤子,全局鉤子,validators,和序列化類型和字段屬性也是
在序列化器類中創(chuàng)建局部鉤子:validate_字段名,并且接收一個(gè)參數(shù)
# ser.py class BooksSerializer(serializers.Serializer): title = serializers.CharField() publish = serializers.CharField() price = serializers.DecimalField(max_digits=5, decimal_places=2) # 局部鉤子對(duì)price字段校驗(yàn) def validate_price(self, data): if float(data) > 20: # 校驗(yàn)成功就通過(guò) return data else: # 校驗(yàn)失敗就拋異常 raise ValidationError('價(jià)格太低')
全局鉤子:validate( ), 接收一個(gè)參數(shù),
同時(shí)對(duì)多個(gè)字段進(jìn)行比較驗(yàn)證
# ser.py class BooksSerializer(serializers.Serializer): title = serializers.CharField() publish = serializers.CharField() price = serializers.DecimalField(max_digits=5, decimal_places=2) def validate(self, validate_data): title = validate_data.get('title') publish = validate_data.get('publish') if not title == publish: return validate_data else: raise ValidationError('書名和出版社不能一致')
使用字段的validators=[func],來(lái)校驗(yàn)
# ser.py # 校驗(yàn)函數(shù) def check_price(data): if float(data) > 10: return data else: raise ValidationError('價(jià)格太低') class BooksSerializer(serializers.Serializer): title = serializers.CharField() publish = serializers.CharField() price = serializers.CharField(validators=[check_price]) # 配置
# views.py class BooksView(APIView): def get(self, request): # 響應(yīng)信息 response_msg = {'status': 200, 'message': '查詢成功'} # 獲取所有數(shù)據(jù) books = Books.objects.all() # 把數(shù)據(jù)誰(shuí)傳到序列化器中 book_ser = BooksSerializer(instance=books, many=True) # 序列化多條需要加 many=True # book_ser.data————》序列化對(duì)象.data————》就是序列化后的字典 # 將查詢結(jié)果添加到響應(yīng)信息內(nèi) response_msg['data'] = book_ser.data return Response(response_msg) # urls.py path('books/', views.BooksView.as_view()),
# views.py class BookView(APIView): def get(self, request, pk): # 響應(yīng)信息 response_msg = {'status': 200, 'message': '查詢成功'} # 獲取要序列化的對(duì)象 book = Books.objects.filter(pk=pk).first() # 要序列化誰(shuí)就把誰(shuí)傳到序列化器中 book_ser = BooksSerializer(instance=book) # book_ser.data————》序列化對(duì)象.data————》就是序列化后的字典 # 將查詢結(jié)果添加到響應(yīng)信息內(nèi) response_msg['data'] = book_ser.data return Response(response_msg) # urls.py re_path(r'^book/(?Ppk>\d+)/', views.BookView.as_view()),
新增數(shù)據(jù)需要在序列化器中重寫create( ) 方法:
注意沒(méi)有傳遞instance實(shí)例,則調(diào)用save()方法的時(shí)候,create()被調(diào)用,相反,如果傳遞了instance實(shí)例,調(diào)用save()方法的時(shí)候,update()被調(diào)用。
# views.py class BookView(APIView): def post(self, request): # 響應(yīng)信息 response_msg = {'status': 201, 'message': '增加成功'} # 修改才有instance,新增沒(méi)有instance,只有data book_ser = BooksSerializer(data=request.data) # 校驗(yàn)字段 if book_ser.is_valid(): book_ser.save() # 需要在序列化器中重寫create()方法 # 保存成功把原數(shù)據(jù)返回 response_msg['data'] = book_ser.data else: response_msg['status'] = 202 response_msg['message'] = '數(shù)據(jù)校驗(yàn)失敗' response_msg['data'] = book_ser.error_messages return Response(response_msg) # ser.py class BooksSerializer(serializers.Serializer): title = serializers.CharField() publish = serializers.CharField() price = serializers.DecimalField(max_digits=5, decimal_places=2) # 重寫create def create(self, validated_data): # validated_data——>傳入的新增數(shù)據(jù) instance = Books.objects.create(**validated_data) # instance——> 新增的字段對(duì)象,需要返回 return instance # urls.py path('book/', views.BookView.as_view()),
修改數(shù)據(jù)需要在序列化器中重寫update( ) 方法:
# views.py class BookView(APIView): def put(self, request, pk): # 響應(yīng)信息 response_msg = {'status': 200, 'message': '修改成功'} # 獲取需要修改的字段對(duì)象 book = Books.objects.filter(pk=pk).first() # 將字段對(duì)象和修改數(shù)據(jù)添加到序列化器中 book_ser = BooksSerializer(instance=book, data=request.data) # 校驗(yàn)數(shù)據(jù) if book_ser.is_valid(): book_ser.save() # 需要在序列化器中重寫update()方法 response_msg['data'] = book_ser.data else: response_msg['status'] = 202 response_msg['message'] = '數(shù)據(jù)校驗(yàn)失敗' response_msg['data'] = book_ser.error_messages return Response(response_msg) # urls.py re_path('book/(?Ppk>\d+)', views.BookView.as_view()),
# views.py class BooksView(APIView): def delete(self, request, pk): # 響應(yīng)信息 response_msg = {'status': 200, 'message': '刪除成功'} # 刪除數(shù)據(jù) Books.objects.filter(pk=pk).delete() return Response(response_msg) # urls.py re_path('book/(?Ppk>\d+)', views.BooksView.as_view()),
DRF提供了ModelSerializer模型類序列化器來(lái)幫助我們快速創(chuàng)建一個(gè)Serializer類。
ModelSerializer與常規(guī)的Serializer相同,但是提供了:
實(shí)例:
class BookSerializer(serializers.ModelSerializer): class Meta: model = Book # 指明參照那個(gè)模型類 fields = '__all__' # 為模型類的那些字段生成
字段操作
1、可以使用fields來(lái)明確字段,__all__表示包含所以字段,具體那些字段->fields = ('title','price')
2、exclude表示排除那些字段,不能和fields一起寫——>exclude = ('price',)
3、額外參數(shù)extra_kwargs,給字段添加額外的參數(shù)
class BookSerializer(serializers.ModelSerializer): class Meta: model = Book # 指明參照那個(gè)模型類 fields = '__all__' # 為模型類的那些字段生成 # 類似于 title = serializers.CharField(read_only = True) extra_kwargs = { 'title': {'read_only': True}, }
當(dāng)我們需要查詢多條數(shù)據(jù)時(shí)就需要在實(shí)例化序列化器的時(shí)候傳many=True
book_ser = BooksSerializer(instance=books, many=True) # 查詢多條 book_one_ser = BooksSerializer(instance=book) # 查詢單條 print(type(book_ser)) #class 'rest_framework.serializers.ListSerializer'> print(type(book_one_ser)) #class 'app01.ser.BookModelSerializer'> # 對(duì)象的生成-->先調(diào)用類的__new__方法,生成空對(duì)象,如果many=True,生成ListSerializer對(duì)象,反之生成Serializer對(duì)象 # 類的__new__方法控制對(duì)象的生成 def __new__(cls, *args, **kwargs): # 如果many=True,就會(huì)自動(dòng)創(chuàng)建ListSerializer類 if kwargs.pop('many', False): return cls.many_init(*args, **kwargs) return super().__new__(cls, *args, **kwargs)
到此這篇關(guān)于drf序列化器serializer的具體使用的文章就介紹到這了,更多相關(guān)drf序列化器serializer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:佳木斯 盤錦 上饒 潮州 湖北 珠海 西寧 宜昌
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《drf序列化器serializer的具體使用》,本文關(guān)鍵詞 drf,序列化,器,serializer,的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。