python Django Rest_Framework框架 APIView介绍与序列化器详解(图文并茂版)

APIView介绍

  • APIViewREST framework提供的所有视图的基类,继承自Django的View类
    APIView与View的不同点为:
  • 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象
  • 视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端期望要求格式
  • 任何APIException异常都会被捕获到,并且处理成合适格式(json)的响应信息返回给客户端
  • 会重新声明了一个新的as_views方法并在dispatch()进行路由分发前,对请求的客户端进行身份认证、权限检查、流量控制

APIView还新增了如下的类属性:

  • authentication_classes 列表或元组,身份认证类
  • permissoin_classes 列表或元组,权限检查类
  • throttle_classes 列表或元祖,流量控制类

序列化器

作用:

  • 序列化:序列化器会将模型对象转换成字典,再通过响应对象(response)转换成json字符串返回给页面
  • 反序列化:把客户端发送过来的数据,通过请求对象(request)转换成字典,序列化器再将把字典转成模型
  • 反序列化:完成数据校验功能

定义序列化器

  • 序列化器(本质就是一个类),一般包括模型类的字段,有自己的字段类型规则。实现了序列化器后,就可以创建序列化对象以及查询集进行序列化操作,通过序列化对象.data来获取数据,再将数据转递给响应对象,即可完成模型数据---->json格式数据的转换
  • 首先创建一个学生模型
from django.db import models


# Create your models here.
class Students(models.Model):
    name = models.CharField(verbose_name='姓名', max_length=255)
    classmate = models.IntegerField(verbose_name='班级')
    studentID = models.IntegerField(verbose_name='学号')
    description = models.TextField(verbose_name='描述')

    class Meta:
        db_table = 'students'

在这里插入图片描述

  • 为学生模型类创建一个序列化器,如下:
from rest_framework import serializers


class StudentsModelSerializers(serializers.Serializer):
    name = serializers.CharField()
    classmate = serializers.IntegerField()
    studentID = serializers.IntegerField()
    description = serializers.CharField()
注意
  • serializer序列化器不止是能为数据库模型类定义,也可以为非数据库模型类的数据定义,serializer序列化器是独立于数据库之外的存在,可以脱离数据库数据单独存在
选项参数
参数名称作用
max_length最大长度
min_lenght最小长度
allow_blank是否允许为空
trim_whitespace是否截断空白字符
max_value最小值
min_value最小值
通用参数
参数名称作用
read_only表明该字段仅用于序列化输出,默认False
write_only表明该字段仅用于反序列化输入,默认False
required表明该字段在反序列化时必须输入,默认True
default反序列化时使用的默认值
allow_null表明该字段是否允许传入None,默认False
validators该字段使用的验证器
error_messages包含错误编号与错误信息的字典
label用于HTML展示API页面时,显示的字段名称
help_text用于HTML展示API页面时,显示的字段帮助提示信息

使用序列化器

序列化
  • 处理服务端响应时,使用序列化器可以完成对数据的序列化
  • 我们只需要在views.py视图函数中使用:
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import Students
from .serilizers import StudentsModelSerializers


class StudentsApiview(APIView):

    def get(self, request):
        # 获取数据集(学生模型对象)
        students_data = Students.objects.all()
        # 实例化序列化器,得到序列化器对象
        ser = StudentsModelSerializers(instance=students_data, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data
        # 响应数据
        return Response(data)

-在数据库中手动添加几条数据,方便展示:
在这里插入图片描述

  • 定义总路由:
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('students.urls')) # students子应用总路由
]
  • 定义子路由
from django.urls import path

from .views import StudentsApiview

urlpatterns = [
    path('students/', StudentsApiview.as_view())
]

在这里插入图片描述

使用序列化器大概分为四步:

  1. 获取需要传递给页面数据集
  2. 实例化序列化器,得到序列化器对象
  3. 调用实例化后的序列化器对象中的data属性方法获取转换后的数据
  4. 将转换的数据传递给Response对象,会自动将数据转换成json数据格式,并返回给页面
参数说明
  • instance:用于序列化,将模型对象传入instance
  • data:与instance作用相反,用于反序列化,将需要反序列化的数据传入data参数
  • many:当数据集的数据量大于一条时,需要传递many=True参数,DRF会自动将多条数据循环处理,再进行返回
反序列化
数据验证

反序列化时数据校验可参考:python Django Rest_Framework框架 反序列化时数据校验的三种方法(图文并茂版)

  • 使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据并将数据转换成模型类对象并保存

  • 在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。

  • 验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名

  • 验证成功,可以通过序列化器对象的validated_data属性获取数据

  • 在定义序列化器时,指明每个字段的序列化类型和选项参数,这就是一种验证行为

  • 通过构造序列化器对象,并将要反序列化的数据传递给data构造参数,进而进行验证

保存数据
  • 数据验证成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象
  • 可以通过实现create()和update()两个方法来实现保存数据
    def create(self, validated_data):
        """新增数据"""
        return validated_data

    def update(self, instance, validated_data):
        """更新数据"""
        return validated_data
  • 实现了上述两个方法后,在反序列化数据的时候,就可以通过save()方法返回一个数据对象的实例,然后自动将数据保存到数据库中

选择调用上述的哪一种方法,是取决于实例化序列化器时传递的参数:

  1. 如果创建序列化器对象的时候,没有传递instance属性,则调用save()方法的时候,create()被调用

  2. 如果传递了instance属性,则调用save()方法的时候,update()被调用

  3. 两个方法都需要传递data属性,才可以使用
    如下举例:

  • views.py
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import Students
from .serilizers import StudentsModelSerializers


class StudentsApiview(APIView):

    def get(self, request):
        # 获取数据集(学生模型对象)
        students_data = Students.objects.all()
        # 实例化序列化器,得到序列化器对象
        ser = StudentsModelSerializers(instance=students_data, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data
        # 响应数据
        return Response(data)

    def post(self, request):
        # 反序列化数据
        student = StudentsModelSerializers(data=request.data)
        # 校验不通过
        if not student.is_valid():
            # 返回错误信息
            return Response(student.errors)
        # 校验通过,保存数据
        student.save()
        # 响应数据
        return Response(student.data)
  • DRF页面自带发送post请求接口,发送如下的json数据:

在这里插入图片描述

  • post请求发送成功后,页面显示成功的响应:
    在这里插入图片描述
  • 查询所有数据,看是否添加成功
    在这里插入图片描述
  • 查看数据库是否添加成功
    在这里插入图片描述

实现单个数据更新、删除、获取

  • 因为我们是对单个数据进行操作,我们需要获取id值进行操作,需要将id值作为路径参数传递给后端,所以需要定义新的路由,新的视图函数
  • 路由文件如下:
from django.urls import path, re_path

from .views import StudentsApiview, StudentDerailApiview

urlpatterns = [
    path('students/', StudentsApiview.as_view()),
    # 单个数据进行操作
    re_path('students/(?P<pk>\d+)/', StudentDerailApiview.as_view())
]
  • 视图文件如下:
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import Students
from .serilizers import StudentsModelSerializers


class StudentsApiview(APIView):

    def get(self, request):
        # 获取数据集(学生模型对象)
        students_data = Students.objects.all()
        # 实例化序列化器,得到序列化器对象
        ser = StudentsModelSerializers(instance=students_data, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data
        # 响应数据
        return Response(data)

    def post(self, request):
        # 反序列化数据
        student = StudentsModelSerializers(data=request.data)
        # 校验不通过
        if not student.is_valid():
            # 返回错误信息
            return Response(student.errors)
        # 校验通过,保存数据
        student.save()
        # 响应数据
        return Response(student.data)


class StudentDerailApiview(APIView):
    # 获取一个学生的信息
    def get(self, request, pk):
        student = Students.objects.get(pk=pk)
        ser = StudentsModelSerializers(instance=student)
        return Response(ser.data)

    # 修改一个学生的信息
    def put(self, request, pk):
        instance = Students.objects.get(pk=pk)
        ser = StudentsModelSerializers(instance=instance, data=request.data)
        if not ser.is_valid():
            return Response(ser.errors)
        ser.save()
        return Response(ser.data)

    # 删除一个学生的信息
    def delete(self, request, pk):
        Students.objects.get(pk=pk).delete()
        return Response({'detail': '删除成功!!'})
  • 获取第一个学生的信息,如下:
    在这里插入图片描述
  • 修改数据成功如下:
    在这里插入图片描述
  • 删除数据如下:
    在这里插入图片描述
说明
  • 在对序列化器进行save()保存时,可以额外传递数据,数据可以在create()和update()中的validated_data参数获取到
  • 默认序列化器必须传递所有required的字段,否则会抛出验证异常。但是我们可以使用partial参数来允许部分字段更新
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值