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。

  

原文地址:https://www.cnblogs.com/jabbok/p/10563876.html