• drf之视图组件以及自动化路由


    两个视图基类APIView、GenericAPIView

    1、APIView类:

    APIView是REST framework提供的所有视图的基类,继承自Django的View父类。

    APIViewView的不同之处在于:

    • 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
    • 视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
    • 任何APIException异常都会被捕获到,并且处理成合适的响应信息;
    • 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

    支持定义的属性

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

    基于APIView类写的接口:

    class BooksView(APIView):
        def get(self, request):
            book_list = Book.objects.all()
            book_ser = Bookserialisers(book_list, many=True)
            return Response(book_ser.data)
    
        def post(self, request):
            book_ser = Bookserialisers(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'code': '101', 'msg': '添加失败', 'data': book_ser.errors})
    class BookView(APIView):
        def get(self, request, pk):
            book = Book.objects.filter(pk=pk).first()
            book_ser = Bookserialisers(book)
            return Response(book_ser.data)
    
        def put(self, request, pk):
            book = Book.objects.filter(pk=pk).first()
            book_ser = Bookserialisers(instance=book, data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response(book_ser.errors)
    
        def delete(self, request, pk):
            ret = Book.objects.filter(pk=pk).delete()
            return Response({'status': 100, 'msg': '删除成功'})

    2、GenericAPIView

    (1)继承APIView类,加入了操作序列化器和数据库操作方法。基于GenericAPIView类的接口如下

    from rest_framework.generics import GenericAPIView
    '''
    属性
    queryset:指明使用的数据查询集
    serializer_class:指明当前视图函数使用的序列化器
    方法:
    get_queryset():返回的是数据库查询结果集,一般数据查询结果有多条数据的时候使用该方法
    get_object():返回的是数据库查询结果(单条),一般是查询结果数据只用一条的时候使用该方法。
    get_serializer:返回序列化对象
    '''
    # GenericAPIView接口
    class Books1View(GenericAPIView):
        queryset = Book.objects
        serializer_class = Bookserialisers
    
        def get(self, request):
            #get_queryset()方法返回的是数据库查询结果集
            book = self.get_queryset()
            #返回序列化对象
            book_ser = self.get_serializer(book, many=True)
            return Response(book_ser.data)
    
        def post(self, request):
            book_ser = self.get_serializer(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'msg': '添加失败'})
    class Book1View(GenericAPIView):
        queryset = Book.objects
        serializer_class = Bookserialisers
    
        def get(self, request, pk):
            #get_boject()返回的是数据库查询结果。
            book = self.get_object()
            book_ser = self.get_serializer(book)
            return Response(book_ser.data)
    
        def put(self, request, pk):
            book = self.get_object()
            book_ser = self.get_serializer(instance=book, data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response(book_ser.errors)
    
        def delete(self, request, pk):
            book = self.get_object().delete()
            return Response({'msg': '删除成功'})

    基于GenericAPIView类的五个视图扩展类

    from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, RetrieveModelMixin,DestroyModelMixin
    from rest_framework.generics import ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView

    这五个类将5个接口分别进行了封装

    类名 方法(需要传参数) 请求方法
    ListModelMixin list() get(查询所有)
    CreateModelMixin create() post
    UpdateModelMixin update() put
    RetrieveModelMixin retrieve() get(查询单个)
    DestroyModelMixin destroy() delete

    基于五个扩展类的接口

    # 五个扩展类
    class Books2View(ListModelMixin, GenericAPIView, CreateModelMixin):
        queryset = Book.objects
        serializer_class = Bookserialisers
    
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)
    class Book2View(GenericAPIView, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin):
        queryset = Book.objects
        serializer_class = Bookserialisers
    
        def get(self, request, pk):
            return self.retrieve(request, pk)
    
        def put(self, request, pk):
            return self.update(request, pk)
    
        def delete(self, request, pk):
            return self.destroy(request, pk)

    注意: GenericViewSet + 五个扩展类接口等价与视图集功能

    #注册
    class Register(GenericViewSet,CreateModelMixin):
        queryset = models.E_User.objects.all()
        serializer_class = User_ser
    #查询
    class Search(GenericViewSet,RetrieveModelMixin):
        queryset = models.E_User.objects.all()
        serializer_class = User_ser
    #更新
    class Update(GenericViewSet,UpdateModelMixin):
        queryset = models.E_User.objects.all()
        serializer_class = User_ser
    
    #等价于
    class update(ModelViewSet)

    GenericAPIView视图九个子类:

    类名 方法:
    ListAPIView get()
    CreateAPIView create()
    RetrieveUpdateAPIView retrieve()
    DestroyAPIView delete()
    UpdateAPIView update
    ListCreateAPIView list(),create(),patch()
    RetrieveUpdateAPIView retrieve(),update(),patch()
    RetrieveDestroyAPIView retrieve(),destroy(),patch()
    RetrieveUpdateDestroyAPIView retrieve(),update(),destroy(),patch()
    #查询所有书籍和添加书籍
    class Books_zuhe(ListCreateAPIView):
        queryset = Book.objects
        serializer_class = Bookserialisers
    #书籍的查删改
    class Book_zuhe(RetrieveUpdateDestroyAPIView):
        queryset = Book.objects
        serializer_class = Bookserialisers

    注意:非视图集的视图接口类,在路由配置中,都是url(r'链接‘,视图类.as_view)

    视图集

    ReadOnlyModelViewSet: 获取一条或者多条接口

    GenericViewSet:ViewSetMixin+GenericApiView

    ViewSet:ViewSetMixin+ApiView

     ModelViewSet继承了GenericViewSet,重写了as_view()方法,提供了action方法。除了默认的五个接口方法外,还可以自己定义新的方法:

    路由文件urls

    urlpatterns = [
    
    url(r'^books/latest/$', views.BookViewSet.as_view({'get': 'latest'})),
        url(r'^books/(?P<pk>d+)/$', views.BookViewSet.as_view({'get': 'retrieve'})),
        url(r'books3/', views.BookViewSet.as_view(actions={'get':'list','post':'create'})),
        url(r'book3/(?P<pk>d+)', views.BookViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
    ]

    基于ModelViewSet类接口代码

    #ModelViewSet接口
    class BookViewSet(ModelViewSet):
        queryset = Book.objects
        serializer_class = Bookserialisers
    
        def latest(self, request):
            """
            返回最新的图书信息
            """
            book = Book.objects.latest('id')
            serializer = self.get_serializer(book)
            return Response(serializer.data)
    
        def read(self, request, pk):
            """
            修改图书的阅读量数据
            """
            book = self.get_object()
            book.bread = request.data.get('read')
            book.save()
            serializer = self.get_serializer(book)
            return Response(serializer.data)

    视图总结:

    #两个基类
    APIView
    GenericAPIView:有关数据库操作,queryset 和serializer_class
    
    
    #5个视图扩展类(rest_framework.mixins)
    CreateModelMixin:create方法创建一条
    DestroyModelMixin:destory方法删除一条
    ListModelMixin:list方法获取所有
    RetrieveModelMixin:retrieve获取一条
    UpdateModelMixin:update修改一条
    
    #9个子类视图(rest_framework.generics)
    CreateAPIView:继承CreateModelMixin,GenericAPIView,有post方法,新增数据
    DestroyAPIView:继承DestroyModelMixin,GenericAPIView,有delete方法,删除数据
    ListAPIView:继承ListModelMixin,GenericAPIView,有get方法获取所有
    UpdateAPIView:继承UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据
    RetrieveAPIView:继承RetrieveModelMixin,GenericAPIView,有get方法,获取一条
    
    
    ListCreateAPIView:继承ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增
    RetrieveDestroyAPIView:继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除
    RetrieveUpdateAPIView:继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改
    RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除
    
    #视图集
    ViewSetMixin:重写了as_view 
    ViewSet:     继承ViewSetMixin和APIView
    
    GenericViewSet:继承ViewSetMixin, generics.GenericAPIView
    ModelViewSet:继承mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet
    ReadOnlyModelViewSet:继承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet

    自动生成路由

    # 第一步:导入routers模块
    from rest_framework import routers
    # 第二步:有两个类,实例化得到对象
    # routers.DefaultRouter 生成的路由更多
    # routers.SimpleRouter
    router=routers.DefaultRouter()
    # 第三步:注册
    # router.register('前缀','继承自ModelViewSet视图类','别名')
    router.register('books',views.BookViewSet) # 不要加斜杠了
    
    # 第四步
    # router.urls # 自动生成的路由,加入到原路由中
    # print(router.urls)
    # urlpatterns+=router.urls

    1、导入routers模块

    from rest_framework import routers 
    #SimpleRouter(一般都使用这个)
    #DefaultRouter(生成路由比较多)

    2、实例化路由类,得到对象:

    router=routers.SimpleRouter()

    3、注册路由

    #register('前缀‘,views文件中我们自定义的视图集函数,别名)
    #url(r'^book/',views.UserModelSet),前缀就等价于url的 book
    router.register('book',views.UserModelSet)

    4、加入到原路由:

    urlpatterns +=router.urls

    生成接口如下:

    #put、get、delete请求方法
    http://127.0.0.1:8000/app04/book/pk/
    #get、post请求
    http://127.0.0.1:8000/app04/book/

    完整代码如下:

    #urls.py文件
    
    from django.conf.urls import url
    from rest_framework.routers import SimpleRouter,DefaultRouter
    from app04 import views
    #实例化对象
    route=SimpleRouter()
    #注册路由
    route.register('book',views.UserModelSet,)
    urlpatterns = [
    
    ]
    #添加路由
    urlpatterns +=route.urls
    
    views.py文件
    
    from app04.models import User,UserToken
    from app04.ser import UserSer,UserToken
    from rest_framework.viewsets import ModelViewSet
    # Create your views here.
    
    class UserModelSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSer
    完整代码如下

    给视图类中自定义函数添加路由

    1、导入一个action装饰器
    
    ```python
    from rest_framework.decorators import action
    ```
    2、在自定义函数中添加action装饰器
    
    ```python
    class UserModelSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSer
    '''
    methods参数对应是一个列表,用来放请求方法
    detail=false,接口连接如下
    #^book/get_2/$ [name='book-get-1']
    detail=True
    #^book/(?P<pk>[^/.]+)/get_2/$ [name='book-get-1']
    detail:是决定是否带pk
    methods是请求方法
    '''
    @action(methods=['get'],detail=False)
    def get_2(self,reqeust):
    user=self.get_queryset()[0:2]
    ser=self.get_serializer(user,many=True)
    return Response(ser.data) 
    ```
    最终给自定义get_2方法添加的路由如下:
    http://127.0.0.1:8000/app04/book/get_2/
    http://127.0.0.1:8000/app04/book/pk/get_2/

    视图类关系图

  • 相关阅读:
    Linux编程之UDP SOCKET全攻略
    Java8 flatMap的sample
    swagger bug
    bash中的pasue
    树、二叉树、满二叉树、完全二叉树概念分清
    复习一下高中数学
    SpringBoot Junit Maven JaCoCo
    事务传播和隔离
    springboot swagger2 泛型踩坑记
    Code::Blocks debug程序
  • 原文地址:https://www.cnblogs.com/nq31/p/13911800.html
Copyright © 2020-2023  润新知