RESTful API接口3(API接口的几种实现方式)

函数式编程 Function Based View

类视图编程 Class Based View

导包

from rest_framework.views import APIView

编写views.py代码

""" 类视图编程 Class Based View """class CourseList(APIView):"""查询课程"""def get(self, request):""":param request::return:"""queryset = Course.objects.all()s = CourseSerializer(instance=queryset, many=True)return Response(s.data, status=status.HTTP_200_OK)"""添加课程"""def post(self, request):""":param request::return:"""s = CourseSerializer(data=request.data)  # 调接口传过来的数据if s.is_valid():s.save(teacher=self.request.user)# 分别是<class 'django.http.request.QueryDict'> <class 'rest_framework.utils.serializer_helpers.ReturnDict'>print(type(request.data), type(s.data))return Response(data=s.data, status=status.HTTP_201_CREATED)return Response(data=s.errors, status=status.HTTP_400_BAD_REQUEST)class CourseDetail(APIView):"""方便共用对象"""@staticmethoddef get_object(pk):try:return Course.objects.get(pk=pk)except Course.DoesNotExist:return"""查询课程"""def get(self, request, pk):""":param request::param pk::return:"""obj = self.get_object(pk=pk)if not obj:return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)s = CourseSerializer(instance=obj)return Response(s.data, status=status.HTTP_200_OK)"""修改课程"""def put(self, request, pk):""":param request::param pk::return:"""obj = self.get_object(pk=pk)if not obj:return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)s = CourseSerializer(instance=obj, data=request.data)if s.is_valid():s.save()return Response(data=s.data, status=status.HTTP_200_OK)return Response(data=s.errors, status=status.HTTP_400_BAD_REQUEST)"""删除课程"""def delete(self, request, pk):""":param request::param pk::return:"""obj = self.get_object(pk=pk)if not obj:return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)obj.delete()return Response(status=status.HTTP_204_NO_CONTENT)

添加路由

urlpatterns = [# FBVpath('fbv/list', views.course_list, name="fbv-list"),  # name 表示网页返回显示的路由地址path('fbv/details/<int:pk>', views.course_details, name="fbv-details"),# Class Based Viewpath('cbv/list', views.CourseList.as_view(), name="cbv-list"),path('cbv/detail/<int:pk>', views.CourseDetail.as_view(), name="cbv-detail")
]

参照上篇文章进行Postman测试;

FBV和CBV区别

  1. 代码风格不同,FBV更容易理解,CBV可读性更好
  2. CBV复用性更好
  3. 路由写法不同

通用类视图 GENERIC Class Based View

对类视图简单操作进行的封装

导包

from rest_framework import generics

编写views.py代码

# 获取 添加
class GCourseList(generics.ListCreateAPIView):# queryset名字必须为这个queryset = Course.objects.all()serializer_class = CourseSerializerdef perform_create(self, serializer):serializer.save(teacher=self.request.user)# 获取 修改 删除
class GCourseDetail(generics.RetrieveUpdateDestroyAPIView):# queryset名字必须为这个queryset = Course.objects.all()serializer_class = CourseSerializer

代码非常简单,可以简单看下源码

在这里插入图片描述
在这里插入图片描述
可以看到源码其实是帮我们实现了类视图写的代码。

添加路由

urlpatterns = [# FBVpath('fbv/list', views.course_list, name="fbv-list"),  # name 表示网页返回显示的路由地址path('fbv/details/<int:pk>', views.course_details, name="fbv-details"),# Class Based Viewpath('cbv/list', views.CourseList.as_view(), name="cbv-list"),path('cbv/detail/<int:pk>', views.CourseDetail.as_view(), name="cbv-detail"),# Generic Class Based Viewpath("gcbv/list", views.GCourseList.as_view(), name="gcbv-list"),path("gcbv/detail/<int:pk>", views.GCourseDetail.as_view(), name="gcbv-detail"),]

参照上篇文章进行Postman测试;

可以看到返回结果已经帮我们做了分页。

在这里插入图片描述

视图集viewsets

导包

from rest_framework import viewsets

编写views.py代码

"""四、 DRF的视图集viewsets"""class CourseViewSets(viewsets.ModelViewSet):queryset = Course.objects.all()serializer_class = CourseSerializerdef perform_create(self, serializer):serializer.save(teacher=self.request.user)

添加路由

两种方式
1.

    # DRF viewsetspath("viewsets", views.CourseViewSet.as_view({"get": "list", "post": "create"}), name="viewsets-list"),path("viewsets/<int:pk>", views.CourseViewSet.as_view({"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}), name="viewsets-detail"),

字典里面key为请求方式,value 为函数名字,可以点进去源码看函数名字

在这里插入图片描述
在这里插入图片描述
随便点进去一个看一下即可:
在这里插入图片描述

导入 routers包

from rest_framework.routers import DefaultRouter

初始化、注册router

router = DefaultRouter()
# prefix 相当于url前缀
router.register(prefix='viewsets', viewset=views.CourseViewSets)

配置path

path("", include(router.urls))

参照上篇文章进行Postman测试;