drf序列化器的实例
应用目录结构:
views.py
from django.shortcuts import render # Create your views here. from django.views import View from django.http import JsonResponse, QueryDict from bookset.models import BookInfo #导入序列化列 from .serializers import BookInfoSerializer ################################################################# #########################序列化########################################## class BookInfoView(View): def get(self,request): #1.操作数据库 books=BookInfo.objects.all() #2.序列化 #创建序列化对象 #参数1:isntance.要序列化的模型数据 #参数2:data要反序列化的字典数据 #参数3:many,是否要序列化多个模型数据,多条数据many=True,默认为false #参数4:context=序列化的上下文.字典类型数据.可以通过context把视图中的数据,传递给序列化器内部使用 serislizer=BookInfoSerializer(instance=books,many=True,) #通过serializer.data获取序列化完成的数据 print(serislizer.data) #3.返回数据 return JsonResponse(serislizer.data,safe=False) ####################################################### # 序列化器反序列化阶段的使用 # 校验数据和字典数据转换成模型 #############################反序列化############################### from django.views import View from django.http import JsonResponse from .serializers import BookInfo2Serializer class BookInfo2View(View): def post(self,request): #添加一本书 #1.接收数据 data=request.POST #2.反序列化,验证数据 #1.验证数据 # 抛出异常 # is_valid调用验证方式:字段选项validators->自定义验证方法[单选项]->自定义验证方法[多选项] # 验证成功后的数据 serializer=BookInfo2Serializer(data=data) ret=serializer.is_valid(raise_exception=True) print(serializer.validated_data) # 转换数据成模型.同步到数据库中 # save会自动调用序列化器类里面声明的create/update方法,返回值是当前新增/更新的模型对象 serializer.save() #3.响应数据 print("====",serializer.data) #这边响应的数据一定是序列化器反序列化后的数据,否则,异常不会返回给前端 return JsonResponse(serializer.data) def put(self,request,pk): '''更新一个图书''' #根据主键获取指定图书信息 book=BookInfo.objects.get(pk=pk) #接受客户端提交过来的数据 data=QueryDict(request.body) print(data) #使用序列化器完成验证和反序列化的过程 #partial=True 接下来在反序列化中允许部分数据更新,针对字段选项必填的情况 serializer=BookInfo2Serializer(instance=book,data=data,partial=False) print("++++++++",serializer) ret=serializer.is_valid() print(ret) #save之所以可以自动识别,什么时候执行create,什么时候执行update, #主要按创建序列化器对象时候,是否有传入instance #有instance参数,则save会调用序列化器中的update #没有instance参数,则save会抵用序列化器内部的create serializer.save() return JsonResponse(serializer.data) ############################################## #3. 模型序列化器 # 1.可以帮助我们自动完成字声明[主要从模型中的字段声明里面提取过来] # 2.模型序列化器要可以帮我们声明create和update的方法和代码 ############################################## from django.views import View from django.http import JsonResponse from .serializers import BookInfoModelSerializer class BookInfo3view(View): def post(self,request): '''添加一本图书''' #接收数据 data=request.POST print(data) #反序列化 serializer=BookInfoModelSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data) def put(self,request,pk): '''更新一本图书''' book=BookInfo.objects.get(pk=pk) #获取数据 data=QueryDict(request.body) #反序列化 serializer=BookInfoModelSerializer(instance=book,data=data,partial=True) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data)
serializers.py(自己创建的,管理序列化器使用)
#!/usr/bin/env python # -*- coding: utf-8 -*- #author tom ################################################## # 序列化器之序列化 ################################################## from rest_framework import serializers from bookset.models import BookInfo class BookInfoSerializer(serializers.Serializer): #自定义要序列化反序列化的字段 id=serializers.IntegerField(label='主键id',read_only=True) btitle=serializers.CharField(label='图书标题') bpub_date=serializers.DateField(label='出版日期') bread=serializers.IntegerField(label='阅读量') bcomment=serializers.IntegerField(label='评论量') is_delete=serializers.BooleanField(label="逻辑删除") ########################################################### # 2 序列化器的反序列化阶段使用 # 主要用户验证数据和字典数据转换成模型 ####################################################### from rest_framework import serializers # is_valid调用验证方式:字段选项validators->自定义验证方法[单选项]->自定义验证方法[多选项] #自定义字段选选项函数(比较少用,一般用内置的) def check_btitle(data): if data=='西厢记': raise serializers.ValidationError('西厢记也好黄啊') #一定要返回数据 return data class BookInfo2Serializer(serializers.Serializer): #自定义反序列化的字段 btitle = serializers.CharField(label='图书标题',min_length=1,max_length=128,validators=[check_btitle]) bpub_date = serializers.DateField(label='出版日期') bread = serializers.IntegerField(label='阅读量',min_value=0) bcomment = serializers.IntegerField(label='评论量',default=0) #表示当前字段可以不填 is_delete = serializers.BooleanField(label="逻辑删除") #自定义验证方法,单字段校验[验证单个字段,可以有多个方法] #格式:def validate_字段名(self,data):#data当前字段对应值 #data是形参,sub写,代表的是当前字段对应的值 def validate_btitle(self,data): if data=='红楼梦': #抛出错误 raise serializers.ValidationError('红楼梦太色请了') #校验过后一定要把数据值返回,否则数据值为空 return data # 多字段校验数据值data是所有字典的内容,字典类型 def validate(self,data): bread=data.get('bread') bcomment=data.get('bcomment') if bread>=bcomment: return data raise serializers.ValidationError('阅读量小于评论量,太假了') def create(self,validated_data): ''' view视图的save会调用此方法 保存数据,把字典转换成模型 :param validated_data: 客户提交过来的,并且经过验证的数据 :return: ''' instance=BookInfo.objects.create( btitle=validated_data.get('btitle'), bread=validated_data.get('bread'), bcomment=validated_data.get('bcomment'), bpub_date=validated_data.get('bpub_date'), is_delete = validated_data.get('is_delete') ) return instance # def update(self,instance,validated_data): # ''' # 更新数据 # instance 本次跟新操作的模型对象 # validated_data: 客户提交过来,并经过验证的数据 # :param instance: # :param validated_data: # :return: # ''' # instance.btitle=validated_data.get("btitle"), # instance.bread = validated_data.get("bread"), # instance.bcomment = validated_data.get("bcomment"), # instance.bpub_date = validated_data.get("bpub_date"), # instance.is_delete = validated_data.get("is_delete"), # # #调用orm在操作 # instance.save() # #返回模型对象 # return instance def update(self,instance,validated_data): """更新数据 instance 本次更新操作的模型对象 validated_data 客户端提交过来,并经过验证的数据 """ instance.btitle=validated_data.get('btitle') instance.bread=validated_data.get('bread') instance.bcomment=validated_data.get('bcomment') instance.bpub_date=validated_data.get('bpub_date') instance.is_delete=validated_data.get('is_delete') # 调用ORM的保存更新操作 instance.save() # 返回模型对象 return instance ######################################################### #3. 模型序列化器 # 1.可以帮助我们自动完成字声明[主要从模型中的字段声明里面提取过来] # 2.模型序列化器要可以帮我们声明create和update的方法和代码,所我们不需要自己写crate和pub_date ######################################################### from rest_framework import serializers from bookset.models import BookInfo class BookInfoModelSerializer(serializers.ModelSerializer): #模型序列化器也可以自定义验证字段(某些数据库不存在,但是需要前端传过来的,可以进行自定义) #例如:验证码,确认密码 class Meta: model=BookInfo fields="__all__" #可以给模型序列 # 化器里面指定的字段设置限制选项 extra_kwargs={ 'bread':{"min_value":0,"required":True}, } # 自定义验证方法[验证单个字段,可以有多个方法] # def validate_<字段名>(self,data): # data当前字段对应的值 def validate_btitle(self, data): # 例如,图书名不能是红楼梦 if data == "红楼梦": # 抛出错误 raise serializers.ValidationError("红楼梦是禁书~") # 验证方法中,把数据值必须返回给字段,否则字段值为空 return data # 自定义验证方法[验证多个或者所有字段,只能出现一次] def validate(self, data): # data 这个是所有字段的内容,字典类型 bread = data.get("bread") bcomment = data.get("bcomment") if bread >= bcomment: return data raise serializers.ValidationError("阅读量小于评论量,数据太假了")
models.py
from django.db import models #定义图书模型类BookInfo class BookInfo(models.Model): btitle = models.CharField(max_length=20, verbose_name='图书标题') bpub_date = models.DateField(verbose_name='出版时间') bread = models.IntegerField(default=0, verbose_name='阅读量') bcomment = models.IntegerField(default=0, verbose_name='评论量') is_delete = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta: db_table = 'book' # 指明数据库表名 verbose_name = '图书' # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): """定义每个数据对象的显示信息""" return "图书:《"+self.btitle+"》" #定义英雄模型类HeroInfo class HeroInfo(models.Model): GENDER_CHOICES = ( (0, 'female'), (1, 'male') ) hname = models.CharField(max_length=20, verbose_name='名称') hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别') hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息') hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书') # 外键 is_delete = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta: db_table = 'heros' verbose_name = '英雄' verbose_name_plural = verbose_name def __str__(self): return self.hname
urls.py
#!/usr/bin/env python # -*- coding: utf-8 -*- #author tom from django.urls import path, re_path from .import views urlpatterns=[ path('books/',views.BookInfoView.as_view()), path("books2/",views.BookInfo2View.as_view()), re_path("books2/(?P<pk>\d+)/",views.BookInfo2View.as_view()), #model path("books3/",views.BookInfo3view.as_view()), re_path("books3/(?P<pk>\d+)/", views.BookInfo3view.as_view()) ]
主路由,项目路由:
urlpatterns = [ path('admin/', admin.site.urls), path('api/',include("bookset.urls")), #学习drf以后,编写的最终版本 path("app/",include("app.urls")), path("ser/",include("ser.urls")) ]