一、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个方法的类)
注意:
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 viewsets
# 封装了ViewSetMixin
# class ViewSetMixin(object) from rest_framework import mixins
# 封装了我们请求的5个方法的类
# class CreateModelMixin(object) # class ListModelMixin(object) # class RetrieveModelMixin(object) # class UpdateModelMixin(object) # class DestroyModelMixin(object) from rest_framework import generics
# 封装了我们获取queryset和serializer方法的类
# class GenericAPIView(views.APIView):
# def get_queryset()
# def get_object()
# def get_serializer()

3、ModelViewSet

restfull规范、DRF视图和路由的更多相关文章

  1. DRF 视图和路由

    Django Rest Feamework 视图和路由 DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们两个 ...

  2. DRF 视图组件,路由组件

    视图组件  -- 第一次封装   -- GenericAPIView(APIView):    queryset = None    serializer_class = None    def ge ...

  3. DRF 的视图,路由和渲染器

    DRF 的视图,路由和渲染器 1 视图 简单的增删改查 : ModelViewSet; 复杂的操作使用APIView 和 GenericViewSet APIView(View) class Home ...

  4. drf 视图使用及源码分析

    前言 drf视图的源码非常的绕,但是实现的功能却非常的神奇. 它能够帮你快速的解决ORM增删改查的重复代码,非常的方便好用. 下面是它源码中的一句话: class ViewSetMixin: &quo ...

  5. Django REST framework基础:视图和路由

    DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Dj ...

  6. Django Rest Framework 视图和路由

    Django Rest Framework 视图和路由   DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们 ...

  7. 使用DRF视图集时自定义action方法

    在我们用DRF视图集完成了查找全部部门,创建一个新的部门,查找一个部门,修改一个部门,删除一个部门的功能后,views.py的代码是这样子的: class DepartmentViewSet(Mode ...

  8. Rest_Framework的视图与路由

    视图与路由 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. Django ...

  9. 视图家族 & 路由组件

    目录 视图家族 & 路由组件 视图集与路由组件 基于 GenericAPIView 的十大接口 基于 generics 包下工具视图类的六大基础接口 视图集 路由组件:必须配合视图集使用 自定 ...

随机推荐

  1. python运行逻辑

    Python程序在解释器上执行分两个过程: 编译:如果Python进程在机器上拥有写入权限,那么它会把程序的字节码保存为一个以 .pyc 为扩展名的文件.当程序运行后,会在源代码的同一个目录下看到 . ...

  2. pd_ds中的hash

    前言 在c++的STL中,提供了一种hash函数,其用法和map是几乎一样的,但是速度却能快接近一倍 使用方法 需要的头文件 #include<ext/pb_ds/assoc_container ...

  3. Dynamics 365出现数据加密错误怎么办?

    本人微信公众号:微软动态CRM专家罗勇 ,回复290或者20181227可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . Dy ...

  4. 超级强大的socket工具ss,替代netstat

    1.结论:ss 命令比netstat 更强大,提供功能更多,并且性能更高. 2.显示当前系统的socket占用总体宏观情况. ss -s 当已创建的socket数过多时,已经说明系统配置存在问题. 3 ...

  5. JavaScript中的高阶函数

    之前写的<JavaScript学习手册>,客户跟我说有些内容不适合初学者,让我删了,感觉挺可惜的,拿到这里和大家分享. JavaScript中的一切都是对象,这句话同样适用于函数.函数对象 ...

  6. git上传新项目到coding

    1:coding.net注册账号,并创建项目.可以将readme.txt打上勾 2:cd到本机的项目文件夹下 在git中代表workspace 3:mac用户用ls -all ,linux用户用ll ...

  7. c/c++ linux 进程间通信系列5,使用信号量

    linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...

  8. SpringMVC相关常用注解

    @Controller: @Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象 @RequestMapping: RequestMappin ...

  9. Burpsuite 之intruder

    首先工具:Burpsuite1.7,DVWA,火狐浏览器代理插件,火狐浏览器,密码字典(以下用Bp代指burpsuite) 启动Bp,启动DVWA,并打开本地代理功能 ​ 开启bp的拦截功能,并在dv ...

  10. jenkins自动化工具使用教程(转)

    自动化构建.测试.部署.代码检测越来越重要.主要有一下几点原因 企业做大,项目变多,多端支持(web,h5,小程序等) 微服务提倡高内聚低耦合,项目因拆分变多 DevOps自动化运维流行 集群化,高可 ...