之前学习了模型序列化和普通序列化,我们用最简单的视图和url实现了对序列化的操作。
而实际上,象之前那种由DRF自动生成所有的视图和url的情况,在应用是使用很少。而需要用户根据实际业务需求,自定义视图和url。
DRF提供了丰富的视图类,可以满足程序员的各种需求,基本上一个需求可以用多种视图来满足。
1 导入包
找到Applications/Exampls/views下的Schools.py文件,先导入以下包:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from GeneralTools.CustomSchema import CustomSchema from coreapi import Field from coreschema import String
APIView根据浏览器url请求中是否带有ID参数分为两类。
2 url不带参请求
url不带参请求:浏览器请求时url中不带参数,主要用于查询和新增,与之对应的是get和post方法
不带参请求的类名格式为:模型名+List
在Schools.py中增加一个类,SchoolListView,代码如下:
class SchoolListView(APIView): schema = CustomSchema( manual_fields={ ‘post‘: [ Field(name=‘name‘, required=True, location=‘form‘, schema=String(description=‘学校名称‘)), Field(name=‘email‘, required=False, location=‘form‘, schema=String(description=‘学校邮箱‘)), Field(name=‘phone‘, required=True, location=‘form‘, schema=String(description=‘学校座机‘)), Field(name=‘employment_rate‘, required=True, location=‘form‘, schema=String(description=‘就业率‘)), Field(name=‘teacher_quantity‘, required=True, location=‘form‘, schema=String(description=‘教师人数‘)), Field(name=‘student_quantity‘, required=True, location=‘form‘, schema=String(description=‘学生人数‘)), Field(name=‘sms_code‘, required=True, location=‘form‘, schema=String(description=‘验证码‘)), ] } ) @classmethod def get(cls, request): """ 【功能描述】用于查询所有学校信息</br> 【返回参数】</br> 1 name:学校名称</br> 2 email:学校电子邮箱</br> 3 phone:学校座机</br> 4 employment_rate:就业率</br> 5 teacher_quantity:教师人数</br> 6 student_quantity:学生人数</br> """ schools = Schools.objects.all() serializer = SchoolsSerializer(schools, many=True) return Response(serializer.data) @classmethod def post(cls, request): """ 【功能描述】用于新增学校信息</br> 【返回参数】</br> 1 成功返回201</br> 2 失败返回出错信息</br> """ serializer = SchoolsSerializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED)
为视图SchoolListViews增加一个url:path(‘SchoolList/‘, SchoolListView.as_view()),并在测试文档中测试,如图:
3 url带参数请求
带参数请求,主要是需要url中带上记录ID进行请求,主要用于查询指定记录(对应get方法),更改指定记录(对应put方法),删除指定记录(对应delete方法)
带参数请求的类名为:模型名+DetailView
在Schools.py中增加一个类,SchoolDetailView,代码如下:
class SchoolDetailView(APIView): schema = CustomSchema( manual_fields={ ‘put‘: [ Field(name=‘name‘, required=True, location=‘form‘, schema=String(description=‘学校名称‘)), Field(name=‘email‘, required=False, location=‘form‘, schema=String(description=‘学校邮箱‘)), Field(name=‘phone‘, required=True, location=‘form‘, schema=String(description=‘学校座机‘)), Field(name=‘employment_rate‘, required=True, location=‘form‘, schema=String(description=‘就业率‘)), Field(name=‘teacher_quantity‘, required=True, location=‘form‘, schema=String(description=‘教师人数‘)), Field(name=‘student_quantity‘, required=True, location=‘form‘, schema=String(description=‘学生人数‘)), Field(name=‘sms_code‘, required=True, location=‘form‘, schema=String(description=‘验证码‘)), ] } ) @classmethod def get(cls, request, pk): """ 【功能描述】根据ID查询指定记录</br> 【返回参数】</br> 1 name:学校名称</br> 2 email:学校电子邮箱</br> 3 phone:学校座机</br> 4 employment_rate:就业率</br> 5 teacher_quantity:教师人数</br> 6 student_quantity:学生人数</br> """ try: school = Schools.objects.get(pk=pk) except Schools.DoesNotExist: raise status.HTTP_404_NOT_FOUND serializer = SchoolsSerializer(school) return Response(serializer.data) @classmethod def put(cls, request, pk): """ 【功能描述】根据ID修改指定记录 【返回参数】</br> 1 name:学校名称</br> 2 email:学校电子邮箱</br> 3 phone:学校座机</br> 4 employment_rate:就业率</br> 5 teacher_quantity:教师人数</br> 6 student_quantity:学生人数</br> """ try: school = Schools.objects.get(pk=pk) except Schools.DoesNotExist: raise status.HTTP_404_NOT_FOUND serializer = SchoolsSerializer(school, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) @classmethod def delete(cls, request, pk): """ 【功能描述】根据ID删除指定学校 【返回参数】</br> 1 成功返回204</br> 2 失败返回出错信息</br> """ try: school = Schools.objects.get(pk=pk) except Schools.DoesNotExist: raise status.HTTP_404_NOT_FOUND school.delete() return Response(status=status.HTTP_204_NO_CONTENT)
为视图SchoolDetailView增加一个url:path(‘SchoolDetail/<int:pk>‘, SchoolDetailView.as_view()),并在测试文档中测试,如图: