APIView是Django REST framework中一个非常重要的抽象基类视图,它提供了一些功能:
1.继承自Django的View类,保留了View原有的属性和方法。
2.提供了更多针对API的方法,比如定义各个请求方法的响应(get, post等)。
3.对请求进行身份认证、权限校验、流量控制等。
4.内容协商,选择合适的renderer来序列化输出。
5.处理常见的异常,提供统一的错误响应。
6.请求解析,包括验证、转换请求内容。
7.模型对象和queryset的处理。
要实现一个API视图,我们需要:
1.继承APIView
2.指定renderer_classes、parser_classes等设置
3.实现get、post等方法,编写视图逻辑
4.加入认证、权限、限流等特性
这样就可以快速构建一个功能完备的API视图了。
相比普通的Django View,APIView提供了更多面向API的特性,可以大大简化视图的编写。如果需要的话,还可以进一步继承GenericAPIView等基类,获得更多功能。所以APIView是一个非常有用的基类,是构建API不可或缺的部分。
APIView 的使用
APIView 列表视图
1.编辑子应用目录下的 views.py 文件,从 rest_framework.views 中导入 APIView 模块,同时,也导入 rest_framework 中响应模块,同时,在该文件中编写 APIView development试图类,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
...
from rest_framework.views import APIView from rest_framework.response import Response
...
class BookInfoAPIView(APIView): """ 列表视图 """ def get(self, request): """ 查询所有的图书数据并返回 :param request: 序列化 :return: """ qs = BookInfo.objects.all()
ser= BookInfoSerializers(instance=qs, many=True)
return Response(ser.data)
def post(self, request): """ 添加数据 步骤: 1.获取数据; 2.对数据进行解码; 3.校验及保存数据; 4.返回新增的数据。 :param request: :return: """ print(request)
book = request.data
ser = BookInfoSerializers(data=book)
ser.is_valid(raise_exception=True)
ser.save()
return Response(data=ser.data, status=201)
|
2.编辑子应用目录下的 urls.py 文件,在默认的 urlpatterns = [..]
中添加访问路由(注意:非 DRF 路由),如下:
1 2 3 4 5 6 7 8 9 10
|
...
urlpatterns = [ ... path('bookapi/', views.BookInfoAPIView.as_view()), ]
...
|
3.打开浏览器,访问路由:
3.1.查询数据:
3.2.增加数据(使用 Apifox 接口调试工具模拟数据),如下图:
APIView 详情视图
1.编辑子应用目录下的 views.py 文件,接上新建一个详情视图类,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
...
class BookInfoDetailAPIView(APIView): """ 详情视图 """ def get(self, request, pk): """ 查询单个数据 :param request: :param pk: 去查询是否有要查询的数据 :return: 返回序列化数据 """ try: book = BookInfo.objects.get(id=pk) except BookInfo.DoesNotExist: return JsonResponse({'error': '没有这个数据!'}) ser =BookInfoSerializers(instance=book)
return JsonResponse(ser.data, status=200 ,json_dumps_params={'ensure_ascii': False})
def put(self, request, pk): """ :param request: :param pk: :return: """ try: book = BookInfo.objects.get(id=pk) except BookInfo.DoesNotExist: return JsonResponse({'error': '没有这个数据!'})
json_data = request.data
ser = BookInfoSerializers(instance=book, data=json_data)
ser.is_valid(raise_exception=True)
ser.save()
return Response(ser.data ,status=201)
def delete(self,request,pk): try: book = BookInfo.objects.get(id=pk) except BookInfo.DoesNotExist: return Response({'error': '没有这个数据!!!'})
book.delete() return Response({'message':'删除成功'}, status=204)
|
2.编辑子应用目录下的 urls.py 文件,在默认的 urlpatterns = [..]
中添加访问路由(注意:非 DRF 路由),如下:
1 2 3 4 5 6 7 8 9 10
|
...
urlpatterns = [ ... re_path('^bookapis/(?P<pk>\d+)/$', views.BookInfoDetailAPIView.as_view() ), ]
...
|
3.打开浏览器,访问路由(注意:这里需要传入 pk 参数的值,即数据库表中数据的 ID 值):
3.1.查询单个数据:
3.2.修改数据:
3.3.删除数据:
GenericAPIView 的使用
GenericAPIView是DRF中一个非常有用的抽象视图基类,它提供了典型的REST框架所需要的核心功能,可以用来快速构建自定义的API视图。
主要特点包括:
- 提供了通用的方法处理函数,如get()、post()等。这些方法会根据请求方法调用相应的处理函数,如get()会调用get方法。
- 处理authentication、permissions、throttling、content_negotiation等功能。
- 提供了操作serializer的方法,如get_serializer、get_serializer_class等。
- 处理pagination,提供了paginate_queryset和get_paginated_response方法。
- 提供了操作queryset的方法,如filter_queryset等。
- 提供了操作response的方法,如response、error_response等。
- 支持通过类属性设置queryset、serializer_class、pagination_class等。
使用GenericAPIView的主要步骤:
1.从GenericAPIView继承,设置queryset、serializer_class等类属性。
2.根据需要定制get()、post()等方法的逻辑处理。
3.在视图使用GenericAPIView提供的各种操作queryset、serializer、pagination、response等方法。
所以GenericAPIView是一个非常强大的抽象基类,使用它可以快速构建自定义的REST风格的API。配合Mixins可以构建CRUD视图,或进一步封装出各种通用视图基类。
GenericAPIView 列表视图
1.编辑子应用目录下的 views.py 文件,从 rest_framework.generics 中导入 GenericAPIView 模块,同时,也导入 rest_framework 中的状态模块 status,同时,在该文件中编写 APIView development试图类,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
...
from rest_framework.generics import GenericAPIView from rest_framework import status
...
class BookInfoGenericAPIView(GenericAPIView): """ 列表试图 """ queryset = BookInfo.objects.all() serializer_class = BookInfoSerializers
def get(self,request):
qs = self.get_queryset()
ser = self.get_serializer(instance=qs, many = True)
return Response(ser.data ,status=status.HTTP_200_OK)
def post(self, request):
book = request.data
ser = self.get_serializer(data=book) ser.is_valid() ser.save() return Response(data=ser.data, status=status.HTTP_200_OK)
|
2.编辑子应用目录下的 urls.py 文件,在默认的 urlpatterns = [..]
中添加访问路由(注意:非 DRF 路由),如下:
1 2 3 4 5 6 7 8 9 10
|
...
urlpatterns = [ ... path('bookgen/', views.BookInfoGenericAPIView.as_view()), ]
...
|
3.打开浏览器,访问路由:
3.1.查询所有数据:
3.2.添加数据:
GenericAPIView 详情视图
1.继上,编辑子应用目录下的 views.py 文件,在最底部添加 GenericAPIView() 详情视图类,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
...
class BookInfoDetailGenericAPIView(GenericAPIView): """ 详情视图集 """
queryset = BookInfo.objects.all() serializer_class = BookInfoSerializers def get(self,request, pk): book = self.get_object() ser = self.get_serializer(book) return Response(ser.data, status=status.HTTP_200_OK)
def put(self,request, pk): book = self.get_object() ser = self.get_serializer(book, request.data) ser.is_valid() ser.save() return Response(ser.data, status = status.HTTP_200_OK)
def delete(self,request, pk): book = self.get_object() book.delete() return Response({'message': '删除成功'}, status=204)
|
2.编辑子应用目录下的 urls.py 文件,在默认的 urlpatterns = [..]
中添加访问路由(注意:非 DRF 路由),如下:
1 2 3 4 5 6 7 8 9 10
|
...
urlpatterns = [ ... re_path('^bookgens/(?P<pk>\d+)/$', views.BookInfoDetailGenericAPIView.as_view()), ]
...
|
3.打开浏览器,访问路由:
3.1.查询单个数据:
3.2.修改数据:
3.3.删除数据: