restfull规范、DRF视图和路由
一、restfull规范的简单介绍
1、介绍
REST:表述性状态转移,是一种web交互方案
资源:在web中只要有被引用的必要都是资源
URI:
URI 统一资源标识符
URL 统一资源定位符
统一资源接口
根据HTTP请求方式的不同对资源进行不同的操作
遵循HTTP请求方式的语义
前后端传输的叫资源的表述
前端展现的叫资源的状态
通过超链接的指引告诉用户接下来有哪些资源状态可以进入
2、restfull规范
核心思想 -- 面向资源去编程 每个url就是资源的体现 尽量用名词不要用动词 -- 根据HTTP请求方式的不同对资源进行不同的操作 URL体现 -- 版本 https://v3.bootcss.com https://bootcss.com/v3 -- 体现是否是API https://v3.bootcss.com/api -- 过滤信息 https://v3.bootcss.com?page=1 -- 尽量用HTTPS 返回值体现 -- 携带状态码 -- 携带错误信息 -- 返回值 get 返回查看的所有或者单条信息 post 返回新增的那条数据 put/patch 返回更新那条数据 delete 返回空 -- 携带超链接
二、DRF的视图的封装
1、为什么要封装
当有很多个表进行增删改查时,实际上很多代码都是相同的,只是要获取的queryset和序列化器等不同,这就导致我们的视图有特别多重复的代码,
因此对视图进行封装,可减少代码的冗余。
2、要封装的原视图

class BookView(APIView): def get(self, request): book_queryset = Book.objects.all() ser_obj = BookSerializer(book_queryset, many=True) return Response(ser_obj.data) # 新增书籍 def post(self, request): book_obj = request.data ser_obj = BookSerializer(data=book_obj) if ser_obj.is_valid(): ser_obj.save() print(ser_obj.validated_data) return Response(ser_obj.data) # 校验不通过返回错误信息 return Response(ser_obj.errors) # 编辑书籍 class BookEditView(APIView): def get(self, request, id): book_obj = Book.objects.filter(pk=id).first() ser_obj = BookSerializer(book_obj) return Response(ser_obj.data) def put(self, request, id): book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) return Response(ser_obj.errors) def delete(self, request, id): book_obj = Book.objects.filter(id=id).first() if book_obj: book_obj.delete() return Response('') return Response('删除对象不存在')
3、第一次封装

# 获取query_set和序列化器的类 class GenericAPIView(APIView): query_set = None serializer_class = None def get_queryset(self): return self.query_set def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs) # 实现get方法的类 # 小知识点:一般Mixin代表的是混合类,单独继承ListModelMixin你去哪里找get_queryset方法 # 因此,其他类继承Mixin类的时候,还应该多继承其他的某些类 class ListModelMixin(object): def list(self, request): queryset = self.get_queryset() ser_obj = self.get_serializer(queryset, many=True) return Response(ser_obj.data) # 实现post方法的类 class CreateModelMixin(object): def create(self, request): # 获取前端传过来的数据 obj = request.data # 用序列化器做校验 ser_obj = self.get_serializer(data=obj) if ser_obj.is_valid(): # 校验通过,新增书籍 ser_obj.save() # 这里的save方法会去调用序列化器的create方法 print(ser_obj.validated_data) # validated_data是通过校验的数据,也会封装到data里面 return Response(ser_obj.data) # 校验不通过返回错误信息 return Response(ser_obj.errors) # 实现编辑的get方法的类 class RetrieveModelMixin(object): def retrieve(self, request, id): book_obj = self.get_queryset().filter(pk=id).first() ser_obj = self.get_serializer(book_obj) return Response(ser_obj.data) # 实现编辑的put方法的类 class UpdateModelMixin(object): def update(self, request, id): book_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) return Response(ser_obj.errors) # 实现删除delete方法的类 class DestroyModelMixin(object): def destroy(self, request, id): book_obj = self.get_queryset().filter(id=id).first() if book_obj: book_obj.delete() return Response("") return Response("删除的对象不存在") # 书籍列表 class BookView(GenericAPIView,ListModelMixin, CreateModelMixin): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) class BookEditView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request, id): return self.retrieve(request, id) def put(self, request, id): return self.update(request, id) def delete(self, request, id): return self.destroy(request, id)
4、第二次封装
由于上面的继承太长了,因此我们细化一点点,其实就是在第一次封装的基础上另外设置一些类来进行了继承。
# 继承上面需要的类,别的类只需继承这个类即可使用这个类继承的方法 class ListCreateModelMixin(GenericAPIView,ListModelMixin, CreateModelMixin): pass class RetrieveUpdateDestroyModelMixin(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): pass # 书籍列表 class BookView(ListCreateModelMixin): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) class BookEditView(RetrieveUpdateDestroyModelMixin): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request, id): return self.retrieve(request, id) def put(self, request, id): return self.update(request, id) def delete(self, request, id): return self.destroy(request, id)
5、第三次封装
1. DRF框架的ViewSetMixin类重写了CBV的as_view方法,使其可以接收参数,路由分发的时候会根据参数进行分发, 继承了ViewSetMixin的类,它的路由as_view可以传参 2. urls.py from django.conf.urls import url from libsys import views urlpatterns = [ url(r'^list/$', views.BookModelView.as_view({"get": "list", "post": "create"})), url(r'^retrieve/(?P<id>\d+)/$', views.BookModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})), ] 3. 第三次封装 from rest_framework.viewsets import ViewSetMixin # 重写as_view使其可以传参 # 继承上面需要的类,别的类只需继承这个类即可使用这个类继承的方法 class ListCreateModelMixin(GenericAPIView,ListModelMixin, CreateModelMixin): pass class RetrieveUpdateDestroyModelMixin(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): pass # 五合一的视图 # ViewSetMixin必须在GenericAPIView前面,因为需要ViewSetMixin先做路由的分发 class ModelViewSet(ViewSetMixin, ListCreateModelMixin, RetrieveUpdateDestroyModelMixin): pass class BookModelView(ModelViewSet): # 这里什么都不用写了,因为as_view重写后,某个请求进来会默认去找它对应的方法 # 这里找不到,就会去父类中找 query_set = Book.objects.all() serializer_class = BookSerializer
6、使用DRF框架帮我们封装好的模块
1. 直接使用DRF自带的ModelViewSet(DRF的ModelViewSet也是继承了ViewSetMixin和那6个方法的类,即ModelViewSet是7合1的类) 注意: DRF中使用queryset,我们自定义的是query_set 用框架封装的视图,我们url上的那个关键字参数要用pk,系统默认的 2. urls.py from django.conf.urls import url from libsys import views urlpatterns = [ url(r'^list/$', views.BookModelView.as_view({"get": "list", "post": "create"})), url(r'^retrieve/(?P<pk>\d+)/$', views.BookModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})), ] 3. 视图 from rest_framework.viewsets import ModelViewSet # 这里的ModelViewSet是DRF给我们的类 class BookModelView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer
三、路由
from rest_framework.routers import DefaultRouter 第一步实例化对象 router = DefaultRouter() 第二步把路由以及视图注册到对象 router.register('list', views.BookModelView) # 路径,视图 第三步生成可传参的路由 urlpatterns += router.urls 注意:用默认生成的路由,必须保证你的视图函数是继承了ViewSetMixin,即你的as_view方法是可以传参的 在浏览器中就可以输入: list/ list/1 list/2 ... 还额外生成了不用模板的数据路由 list.json list/1.json
四、DRF框架视图类
1、DRF给我们提供的所有视图,都在这几个模块下
from rest_framework import views from rest_framework import viewsets from rest_framework import mixins from rest_framework import generics
2、这几个模块主要封装的类
from rest_framework import views # 封装了APIView class APIView(View) from rest_framework import generics # 封装了我们获取queryset和serializer_class方法的类 class GenericAPIView(views.APIView): def get_queryset() def get_object() def get_serializer() from rest_framework import mixins # 封装了我们请求的5个方法的类 # 获取全部:{"get": "list", "post": "create"} # 编辑和删除某个对象:{"get": "retrieve", "put": "update", "delete": "destroy"} # 创建新对象 class CreateModelMixin(object) # 获取所有对象 class ListModelMixin(object) # 获取指定编辑的对象 class RetrieveModelMixin(object) # 更新指定编辑的对象 class UpdateModelMixin(object) # 删除指定的对象 class DestroyModelMixin(object) from rest_framework import viewsets # 封装了ViewSetMixin,使得CBV的as_view方法或根据http请求去执行对应的方法(mixins的那五个方法) class ViewSetMixin(object) class GenericViewSet(ViewSetMixin, generics.GenericAPIView) # ModelViewSet继承了所有方法,即:我们视图继承了ModelViewSet,那么增删改查方法已经默认写好了 # 只要as_view对http方法进行分发即可。即ModelViewSet是7合1的类 class ModelViewSet( mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet, )
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix