Fork me on GitHub

RESTframwork之视图view

一 在view.py 中:

class AuthorView(APIView):
    def get(self, request):
        author_list = Author.objects.all()

        # 方式1: Django的序列化组件
        # ret=serialize("json",publish_list)
        # 方式2:rest的序列化
        As = AuthorSerializers(author_list, many=True)
        # 序列化数据

        return Response(As.data)

    def post(self, request):

        # 添加一条数据
        print(request.data)

        As = AuthorSerializers(data=request.data)
        if As.is_valid():
            As.save()  # 生成记录
            return Response(As.data)
        else:

            return Response(As.errors)


class AuthorDetailView(APIView):
    def get(self, request, pk):
        author_obj = Author.objects.filter(pk=pk).first()
        As = AuthorSerializers(author_obj, many=False)

        return Response(As.data)

    def put(self, request, pk):
        author_obj = Author.objects.filter(pk=pk).first()
        print(request.data,author_obj)
        # 结果为:{'name': '莫言1', 'age': 88, 'authorDetail': 2} 周围
        As = AuthorSerializers(data=request.data, instance=author_obj)
        if As.is_valid():
            As.save()  # update
            return Response(As.data)
        else:
            return Response(As.errors)

    def delete(self, request, pk):
        Author.objects.filter(pk=pk).delete()

        return Response("")

 

mixin类编写视图:

初步封装方法:如果按照这种方式,我们每个类都需要重复写大量的代码:所以为了解决这个问题,我们对类进行封装。

from rest_framework import mixins
from rest_framework import generics

class BookView(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):

    queryset = Book.objects.all()
    serializer_class = BookSerializers

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)



class BookDetailView(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializers

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

 

进一步封装:

通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py模块。


from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
from rest_framework import generics


class AuthorView(generics.ListCreateAPIView):
'''
因为ListCreateAPIView继承了:
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView)
'''

queryset=Author.objects.all
serializer_class=AuthorSerializers

class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
'''
因为继承了:class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView)
'''
queryset = Author.objects.all
serializer_class = AuthorSerializers
 

终极封装:

from rest_framework.viewsets import ModelViewSet
'''
我们可以看下ModelViewSet中源码的解释:
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.
    """
    提供了create()`, `retrieve()`, `update()`, `partial_update()`, `destroy()` and `list()`
     这样六种方法。
'''

class AuthorModelView(ModelViewSet):

    queryset=Author.objects.all()
    serializer_class=AuthorSerializers

关于终极封装我们需要知道:

我们首先看url中传入的参数,这个时候我们为了区分两种GET请求,那么我们需要在as_view()中传值,初始化的时候就会执行as_view()方法,返回一个view方法。

当请求来的时候会执行view函数,执行到dispatch的时候发现执行不下去了,这个时候我们只能去APIView中去找到我们的dispatch方法。那么这里为什么去APIView中去执行

dispatch方法呢:

APIView(View)

GenericAPIView(views.APIView)  这个类中没有dispatch方法。

 ViewSet(ViewSetMixin, views.APIView):

 

那么我们整个ViewSet最关键的就是这么三行代码:

 for method, action in actions.items():
                handler = getattr(self, action)
                setattr(self, method, handler)
执行完这三行代码,我们的GET对应的方法就变成了list,POST变成CREATE方法。

 

 


 

 

posted @ 2018-08-02 16:58  道阻切长  阅读(105)  评论(0编辑  收藏  举报