ModelViewSet是封装度最高的DRF的视图类。包含了怎删改查中的所有接口操作。
它继承自
GenericViewSet
、ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。!!!!!注意,因为继承关系,必须在内部定义属性,queryset和serializer_class,因此,ModelViewSet通常结合ModelSerializer使用
所以,在使用ModelViewSet定义API时,我们只需要套用模板即可
使用视图集,可以将一系列逻辑相关的动作放到一个类中:
视图集类不再实现get()、post()、put()、delete()方法,而是实现动作 action。 如 list()、retrieve()、create()、update()、destory()
请求 | url | 对应方法 | 备注 |
---|---|---|---|
get | 127.0.0.1:8000/app01/book/ | list | ListModelMixin |
get | 127.0.0.1:8000/app01/book/{1}/ | retrieve | …Mixin |
post | 127.0.0.1:8000/app01/book/ | create | …Mixin |
put | 127.0.0.1:8000/app01/book/{1}/ | update | …Mixin |
detete | 127.0.0.1:8000/app01/book/{1}/ | destroy | …Mixin |
get | 127.0.0.1:8000/app01/book/ user_action | useraction | 自定义 |
post | 127.0.0.1:8000/app01/book/ user_action | useraction | 自定义 |
#views中
class BookInfoViewSet(ModelViewSet):
"""增删改查图书信息"""
# 指定查询集
queryset = BookInfo.objects.all()
# 指定序列化器
serializer_class = BookInfoModelSerializer
定义好了API视图后,需要在路由中,将请求方法与action进行绑定
from django.conf.urls import url
from django.urls import path,include
from . import views
#导入路由控制类
from rest_framework.routers import SimpleRouter,DefaultRouter
#实例化路由控制对象
router = DefaultRouter()
#注册
router.register(r'book',views.BookInfoViewSet)
#编写路由,固定写法,不清楚是否还有其他写法
urlpatterns = [
url(r'',include(router.urls)),
]
DRF框架提供的action根本不能满足某些奇葩需求,这时候,就需要自定义
action
只需要在ModelViewSet定义的api类中,自定action函数后,再将自定义的函数在路由中绑定即可
def 函数名(self, request):
'''
自定义action
return: JSON数据
'''
pass
#示例:
def latest(self, request):
'''获取最后一条记录'''
# 获取模型数据
book = BookInfo.objects.latest('id')
# 获取序列化器对象
s = BookInfoModelSerializer(instance=book)
return Response(s.data)
#路由
urlpatterns = [
url(r'^books/$', views.BookInfoViewSet.as_view({
'get':'action函数名'})),
#示例:
url(r'^books/$', views.BookInfoViewSet.as_view({
'get':'latest'})),
]
之后,使用
http://127.0.0.1:8000/app01/books/
进行测试
或者使用装饰器方法:
from rest_framework.decorators import action
@action(methods=['get'],detail=False,url_path='bookw')
def use(self,request):
return Response({
'name':'天听'})
'''
http://127.0.0.1:8000/app01/book/bookw/
如果不加url_path,路由就成了http://127.0.0.1:8000/app01/book/use/
'''
注意,此写法不需要再注册路由,需要在装饰器内部进行定义
url_path
如果不定义url_path
,路由默认为函数名
detail=False
表示不需要匹配主键的正则,函数不需要传入主键就设为False