APIView介绍
- APIView是REST 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
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 = 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'))
]
from django.urls import path
from .views import StudentsApiview
urlpatterns = [
path('students/', StudentsApiview.as_view())
]
使用序列化器大概分为四步:
- 获取需要传递给页面数据集
- 实例化序列化器,得到序列化器对象
- 调用实例化后的序列化器对象中的data属性方法获取转换后的数据
- 将转换的数据传递给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()方法返回一个数据对象的实例,然后自动将数据保存到数据库中
选择调用上述的哪一种方法,是取决于实例化序列化器时传递的参数:
-
如果创建序列化器对象的时候,没有传递instance属性,则调用save()方法的时候,create()被调用 -
如果传递了instance属性,则调用save()方法的时候,update()被调用 -
两个方法都需要传递data属性,才可以使用 如下举例:
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 = 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 = 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参数来允许部分字段更新
|