drf视图类及路由设置

drf两个基类

1.APIView

​ 该类是继承了django原生view类的drf类,他重写了django类的as_view方法,将request换成了自己的request,并做了认证等功能

​ ps:可以从rest_framework.views

2.GenericAPIView

​ 该类继承了APIView是对APIView的进一步封装

​ ps:可以从 rest_framework.generics 导入

1
2
3
4
5
6
7
8
9
10
11
12
#继承该类后你只需要在类的开头为类添加queryset,serializer_class
#之后每次之后每次只需要调用get_queryset()就可以或得queryset对象
#每次只需要调用get_serializer()就可以或得序列化器对象对象
class Books(GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serialize.BookSerializer

def get(self, request, *args, **kwargs):
queryset = self.get_queryset()
ser = self.get_serializer(instance=queryset, many=True)
print(ser.data)
return Response(ser.data)

5个视图扩展类

基于drf的两个基类又扩展出了5个扩展类,他们是基于上述两个基类之后又进行了一步封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
可以从rest_framework.mixins中导入 
这五个类需要与GenericAPIView类一起使用
CreateModelMixin #创建数据 依然需要写post()
DestroyModelMixin #删除单条数据 依然需要写delete()
UpdateModelMixin # 更新数据库数据 依然需要写put()
ListModelMixin # 获得多条数据 需要写名词复数类的get()
RetrieveModelMixin #获得单条数据 需要写名词类的get()

这些类的内部做的就是我们之前写的调用序列化器,将queryset对象传入等操作,这样我们只需要做到简单的调用方法即可
class Books(GenericAPIView,ListModelMixin):
queryset = models.Book.objects.all()
serializer_class = serialize.BookSerializer

def get(self,request,*args,**kwargs): # 写get方法
return self.list(request,*args,**kwargs)

9个子类视图

这九个子类视图则是对五个视图扩展类的进一步封装,上述五个视图扩展类还需要我们写get等方法,接下来我们只需要通过继承,就可以实现我们需要的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
这九个子类视图我们可以通过rest_framework.generics获得
下述五个实现了基本功能
CreateAPIView ,GenericAPIView,CreateModelMixin
ListAPIView
DestroyAPIView
UpdateAPIView
RetrieveAPIView

下述4个则是功能的混合搭配
ListCreateAPIView:同时具备查询多个以及创建数据的功能
RetrieveDestroyAPIView:具备查询一个以及删除的功能
RetrieveUpdateAPIView:具备查询一个以及更新的功能
RetrieveUpdateDestroyAPIView:具备查询一个以及更新以及删除的功能

视图集

ModelViewSet类则是对上述代码的进一步封装,我们只需要继承该类并在路由中进行一定的配置就可以简单的完成路由与视图的搭配

1
2
3
4
5
6
7
8
该类需要从rest_framework.viewsets中导入

这个类继承了五个视图扩展类以及GenericViewSet
GenericViewSet:该类继承了ViewSetMixin, generics.GenericAPIView
ViewSet:该类继承ViewSetMixin和APIView
其中的重点便是ViewSetMixin该混合类重写了as_view方法,正是由于重写的这个方法帮助我们做到了视图与类方法的映射

ps:ReadOnlyModelViewSet:继承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet,该类不具备写入的功能

路由设置

我们让一个类继承了ModelViewSet之后我们便需要对视图进行一定的修改

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
方式一:
最原始的直接写

下述两个方法都需要继承ModelViewSet之后才能使用
方式二:
url(r'^books/', views.Books.as_view({'get':'list'}#这里写一个字典代表映射关系)),当get请求过来的时候会执行list方法

方式三:自动化创建路径
from rest_framework import routers
router = routers.SimpleRouter()
router.register('路径前缀',指定的视图类 )
eg:router.register('books', views.Books )

若使用方式三自动创建路径,若我们需要指定运行的方法时该如何做
from rest_framework.decorators import action 导入action装饰器
在你需要执行的类方法上添加该装饰器

class Books(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serialize.BookSerializer

@action(methods=['get'],detail=False) #当get方法来的时候执行该类方法
def aaa(self,request):
print(self.action)
return Response('OK')

action参数的含义:
-methods:什么请求方式会触发被装饰函数的执行
-detail:是True是基于带id的路由生成的,如果是False,是基于不带id的路由生成的