函数式编程 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区别
- 代码风格不同,FBV更容易理解,CBV可读性更好
- CBV复用性更好
- 路由写法不同
通用类视图 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测试;


