DRF--【视图集】详解
㈠ . ViewSet 视图集
ViewSetMixin里重写了as_view方法,可以更方便的绑定actions。
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上
常用视图集的父类:
1) ViewSet
继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
2)GenericViewSet
继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发,当然,他也没有提供任何的action方法。
3)ModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
4)ReadOnlyModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin;
action属性:
比如:
urlpatterns = [
url(r’^books/ $ ‘, views.BookInfoViewSet.as_view({‘get’: ‘list’})),
url(r’^books/latest/$ ‘, views.BookInfoViewSet.as_view({‘get’: ‘latest’})),
url(r’^books/(?P\d+)/$ ‘, views.BookInfoViewSet.as_view({‘get’: ‘retrieve’})),
url(r’^books/(?P\d+)/read/$’ , views.BookInfoViewSet.as_view({‘put’: ‘read’})),
]
在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个
现在以ModelViewSet 做代码案例演示:
class BookInfoAPIView(ModelViewSet):
# 定义视图的查询集
queryset = BookInfo.objects.all()
# 指定视图对应的序列化器
serializer_class = BookInfoModelSerializer
# url.py中的urlatterns配置
url(r'books/(?P<pk>\d+)/$', views.BookInfoAPIView.as_view({'get': 'retrieve'})),
url(r'books/', views.BookInfoAPIView.as_view({'get': 'list'}))
在继承了ModelViewSet之后,我们只要在路由中配置的时候,说明什么请求对应什么action,就可以很简单的完成视图函数的关于数据库的简单的增删改查。
㈡ . 路由router
上面的方式定义路由,相对来说,还是比较繁琐的,我们现在可以使用更简单的。
REST framework提供了两个router:
- SimpleRouter
- DefaultRouter
DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。
使用方法:
(1):创建router对象,并注册视图集
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'books', BookInfoAPIView, base_name='book')
register(prefix, viewset, base_name)
- prefix 该视图集的路由前缀
- viewset 视图集
- base_name 路由名称的前缀
(2):添加路由数据到urlpatterns中
有下面两种方式都可以
urlpatterns = [
...
]
urlpatterns += router.urls
urlpatterns = [
...
url(r'^', include(router.urls))
]
路由router形成URL的方式:
㈢ . 视图集中定义附加action动作
虽然ModelViewSet给我们提供了很简单的定义视图函数的方法,但是,并不能满足咱们的所有需求,所以我们得需要自己定义action动作。
添加自定义动作需要使用rest_framework.decorators.action
装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:
- methods: 该action支持的请求方式,列表传递
- detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
detail参数:
- True 表示使用通过URL获取的主键对应的数据对象
- False 表示不使用URL获取主键
class BookInfoAPIView(ModelViewSet):
# 定义视图的查询集
queryset = BookInfo.objects.all()
# 指定视图对应的序列化器
serializer_class = BookInfoModelSerializer
# 自定义action动作
@action(methods=['get'], detail=False)
def latest(self, request):
# 本action是获取最新的书
book = BookInfo.objects.latest('id')
ser = self.get_serializer(book)
return Response(ser.data)
㈣. 视图函数继承关系
这个是从pycharm直接导出的,可以根据图示将视图之间的继承关系梳理清楚。