DRF教程4-视图集和路由类
rest框架包括一个处理viewset的抽象,允许开发人员集中精力处理api交互和建模,url构造都根据常见方式自动处理。
ViewSet类 几乎和VIew类一样,不过它提供read,update这样的操作,而不是get,put。
Refactoring to use ViewSets
现在来重构之前的view代码。首先把CourseList和CourseDetail重构为一个简单的CourseViewSet。
from rest_framework import viewsets
from .models import Course
from .serializer import CourseSerializer
class CourseViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Course.objects.all()
serializer_class = CourseSerializer
#继承自ModelViewSet类,就是说已经自带了视图集的五个action
#就是说向外暴露了五个操作接口
有时候只需要 提供只读信息,那么就只能list和retrieve,就需要只读接口
from rest_framework import viewsets
from .models import UserProfile
from .serializer import UserProfileSerializer
class UserProfileViewSet(viewsets.ReadOnlyModelViewSet):
"""
retrieve : return a user info
list: return all the user info
"""
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
#只向外暴露retrieve和list接口
自定义接口
ModelViewSet提供了全部接口,ReadOnlyModelViewSet提供了list和get接口,
接口肯定要把不必要的接口类型禁用,比如delete。
如果需要delete之外的全部接口,就需要重写视图类
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
#阅读viewsets的源码,可知本质就是把mixins的几个子类引入进来
#不同接口引入不同的类
#先引入相关类
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
class GameGroupViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
retrieve:
返回指定信息
list:
返回列表
update:
更新信息
partial_update:
更新部分字段
"""
queryset = GameGroup.objects.all()
serializer_class = GameGroupSerializer
#重写视图类
重写get_queryset
在视图类中,queryset属性一般就是model.objects.all(),但很多情况下是要对数据进行筛选修改的,所以就需要重新
class SvrFormalViewSet(viewsets.ReadOnlyModelViewSet):
"""
retrieve:
返回指定信息
list:
返回列表
"""
serializer_class = SvrSerializer
def get_queryset(self):
q = ~Q(sid__in = [5000,5012,5020]) #去掉测试区
appids = []
_appids = list(Svrconfig.objects.filter(q).values('id')) #嵌套字典的列表
for appid in _appids: #转化appid的列表
appids.append(appid['id'])
details = Svr.objects.filter(appid__in = appids)
return details
#得到的查询集不再all(),而是修改过的details
Binding ViewSets to URLs explicitly
viewset只是带进了一组action,比如list,create等。
在url中,把http方法绑定到相关的动作上。请求get,就路由到list,请求post action,就请求道create action。
courseList = views.CourseViewSet.as_view({
"get": "list",
"post": "create"
})
courseDetail = views.CourseViewSet.as_view({
"get": "retrieve",
"put": "update",
"delete": "destroy"
})
urlpatterns = [
path('admin/', xadmin.site.urls),
path('course/', courseList,name='course_list'),
path('course/<int:pk>/', courseDetail ,name='course_detail'),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Using Routers
使用routers,需要做的是使用路由器注册适当的视图集,而其余的资源连接可以使用Router类自动处理。
可见,course资源相关的,只需要一个url,其他router会自动处理。
可选参数,base_name: 用来生成urls名字,如果viewset中没有包含queryset, base_name一定要有
from django.urls import path,include
from rest_framework.routers import DefaultRouter
from courses.views import CourseViewSet
import xadmin
router = DefaultRouter()
router.register('course', CourseViewSet,base_name='course')
urlpatterns = [
path('admin/', xadmin.site.urls),
path('', include(router.urls)),
]
#不再需要在app里创建urls文件,只需要在项目目录下将资源的视图集注册到router。

浙公网安备 33010602011771号