drf之视图类

1.两个基类

1APIView

rest_framework.views.APIView

 APIViewREST framework提供的所有视图的基类,DjangoView类的子类。

drf中的APIViewDjango中的View的不同:

传入到视图方法中的是REST frameworkRequest对象,而不是DjangoHttpRequeset对象;

视图方法可以返回REST frameworkResponse对象,视图会为响应数据设置(render)符合前端要求的格式;

任何APIException异常都会被捕获到,并且处理成合适的响应信息;

在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

 支持定义的属性

authentication_classes 列表或元祖,身份认证类
permissoin_classes 列表或元祖,权限检查类
throttle_classes 列表或元祖,流量控制类

APIView中仍以常规的类视图定义方法来实现get() post() 或者其他请求方式的方法。

2GenericAPIView:通用视图类                                                

rest_framework.generics.GenericAPIView

APIView类的子类。相比增加了操作序列化器和数据库查询的方法。增加了对列表视图和详情视图可能用到的通用支持方法。通常和一个或者多个mixin扩展类搭配使用

支持定义的属性:

列表视图和详情视图通用:                                              

queryset:视图的查询集

serializer_class:视图使用的序列化器

列表视图使用:                                                    

pagination_class:分页控制类

filter_backends: 过滤控制后端

详情视图使用:                                                                                                                                            

lookup_field:查询单一数据库对象时使用的条件查询,默认为”pk”。

lookup_url_kwarg:查询单一数据时URL中的参数关键字名称,默认与lookup_field相同

提供的方法:

列表视图和详情视图通用:                                                   

get_queryset(self):返回视图使用的查询集。是视图获取数据的基础。默认返回queryset属性。可以重写自定义。

get_serializer_class(self):返回序列化器类,默认返回serializer_class属性,也可以重写。

get_serializer(self, *args, **kwargs):返回序列化器对象,被其他视图或者扩展类使用。如果想在视图中获取序列化对象,可以通过此方法得到。

详情视图使用的方法:                                                              

get_object(self):返回详情页视图所需的模型类数据对象。默认使用lookup_file属性来过滤queryset对象。在视图类中调用此方法可以获得详情信息的模型类对象。

例子:

get_querset(self)
def get_querset(self):
    user = self.reques.user
    return user.account.all()

get_serializer_class(self)
def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer

#url(r’^book/(?P<pk>\d+)/$’, views.BookDetailView.as_view()),

class BookDetailView(GenericAPIView):
    queryset = BookInfo.objects.all()    #指定查询集
    serializer_class = BookInfoSerializer  #指定序列化器

    def get(self, request, pk):
        book = self.get_object()    #获取查询集(pk就是get_object。多个就是queryset)
        serializer = self.get_serializer(book)  #创建序列化器对象
        return Response(serializer.data)

GenericAPIView的这些方法,要配合扩展类mixin使用,就大大优化了。

2. 5个扩展类mixin

5个扩展类分别是:

ListModelMixin:提供list方法快速实现列表视图。

CreateModelMixin:提供create方法快速实现创建资源视图

RetrieveModelMixin:提供retrieve方法,快速返回一个存在的数据对象(需传入pk

UpdateModelMixinupdate方法,更新一个存在的数据对象。partial_update,局部更新。

DestoryModelMixin:提供destory方法,快速删除一个已经存在的对象。

1ListModelMixin:列表视图扩展类

功能:快速实现列表视图、对数据进行过滤和分类。成功返回200状态码

源代码:

class ListModelMixin(object):
    def list(self, request, *args, **kwargs):
    #过滤
        queryset = self.filter_queryset(self.get_queryset())
    #分页
    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)
    #序列化
    serializer = self.get_serializer(queryset, many=true)
    return Response(serializer.data)

例子:

from rest_framework.mixins import ListModelMixin
class BookListView(ListModelMixin, GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request):
        return self.list(request)

父类帮我们把return之前的事情都做了,只需调用方法,传入参数就行。

2CreateModelMixin:创建视图扩展类

提供create(request, *args, **kwargs),实现快速创建资源的视图,成功返回201状态码。

3RetrieveModelMixin:详情视图扩展类

提供retrieve(request, *args, **kwargs),快速返回一个存在的数据对象。如果存在,返回200

例子:

class BookDetailView(RetrieveModelMixin, GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        retunrn self.retrieve(request)

4UpdateModelMixin:更新视图扩展类

5DestoryModelMixin:删除视图扩展类

 注意:上面的扩展类都和GenericAPIView搭配使用。不然谁给它那些类属性。

 上面还能再简化。APIView

(1)CreateAPIView:提供post方法,相当于GenericAPIView+CreateModelMixin,也继承了二者
(2)ListAPIView:提供get方法。继承自GenericAPIView、ListModelMixin
(3)RetrieveAPIView:提供get方法。继承GenericAPIView、RetrieveModelMixin
(4)DestoryAPIView:提供delete方法
(5)UpdateAPIView:提供put和patch方法
(6)RetrieveUpdateAPIView:提供get、put和patch方法。继承三者
(7)RetrieveUpdateDestoryAPIView:提供get、put、patch、delete方法。继承4者
     
    所以,代码中的mixins.RetrieveModelMixin, GenericAPIView可以写成RetrieveAPIView

3.视图集

1ViewSet

前面的父类仍需写很多函数。ViewSet将几个操作放到一起(前面都是分开实现的)

list()  :提供一组数据
retrieve():提供单个数据
create():创建数据
update():更新数据
destory():删除数据

ViewSet主要通过继承ViewSetMixin来实现在调用as_views()时传入字典({“get”:”list”})的映射。

ViewSet中,没有提供任何动作acton方法,需要我们自己实习那action方法。

ViewSet视图集类不再实现get()post()方法,而是实现动作list()create()等方法。

例子:

#视图中
class BookInfoViewSet(viewsets.ViewSet):

    def list(self, request):
    books = BookInfo.all()
    serializer = BookInfoSerializer(books, many=True)
    return Response(serializer.data)

    def retrieve(self, request, pk=None):
        try:
            books = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return Response(status=status.HTTP_$)$_NOT_FOUND)
        serializer = BookInfoSerializer(books)
        return Response(serializer.data)
#urls.py中
url(r’^books/$’, BookInfoViewSet.as_view({“get”:”list”})),
url(r’^books/(?P<pk>\d+)/$’, BookInfoViewSet.as_view({“get”:”retrieve”})),

视图集只在使用as_view()方法时,才会将action动作与具体的请求方法对应上。

2GenericViewSet

使用ViewSet并不方便,需要自己写listupdate等方法。而这些方法与Mixin扩展类提供的方法同名,可以通过继承Mixin扩展类来复用这些方法,不用自己编写。Mixin扩展类依赖于GenericAPIView,所以还要继承GenericAPIView.

GenericViewSet就包括了GenericAPIViewViewSet,然后再加上不同的扩展类,就复用了扩展类的方法。

 例子:

class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

#设置url
urls.py中
url(r’^books/$’, BookInfoViewSet.as_view({“get”:”list”})),
url(r’^books/(?P<pk>\d+)/$’, BookInfoViewSet.as_view({“get”:”retrieve”})),

3ModelViewSet

ModelViewset继承了GenericViewSet,同时包括所有的5大扩展类。

例子:

class BookInfoViewSet(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoAllSeirializer

如果没有写方法,那么在urls中要以router的方式配置注册路由。

需要什么方法,在url中配置什么字典就行。

4ReadOnlyModelViewset

继承自GenericViewSet,同时也包括ListModelMixinRetrieveModelMixin。只查

 例子:

class BookInfoViewSet(ReadOnlyModelViewSet):
#使用视图集返回列表和单一数据
    serializer_class = BookInfoSerializer
    queryset = BookInfo.objects.all()

    @action(method=[‘get’], detail=False) 
    def latest(self, request):
        book = BookInfo.objects.latest(‘id’)  #取id最后一个
        serializer = self.get_serializer(book)
        return Response(serializer.data)
action装饰器,给自定义的方法生成url地址,不需要在路由中设置。
两个参数:
    methods:声明action对应的请求方式,列表传递。
    detail:声明该action的路径时要不要加主键pk。
        True此时路径为xxx/<pk>/action方法名。
        False此时路径为xxx/action方法名。

 

posted @ 2020-07-09 13:28  yq055783  阅读(240)  评论(0编辑  收藏  举报