drf 六

作者: 吃可爱长大鸭 | 来源:发表于2022-01-19 18:45 被阅读0次

    目录

    1.过滤Filtering
    2.内置过滤类的使用
    3.第三方过滤类使用(django-filter)
    4.自己定义过滤类
    5.排序
    6.异常处理 Exceptions
    7.REST framework 自定义异常处理
    8.REST framework定义的异常
    9.自动生成接口文档
    

    过滤Filtering

    1 过滤针对于 list,获取所有(对于列表数据可能需要根据字段进行过滤)
    2 在请求路径中带过滤条件,对查询结果进行过滤
    

    演示准备

    # models.py 表模型
    from django.db import models
    
    class Book(models.Model):
        name = models.CharField(max_length=34)
        price = models.IntegerField()
    
    # serializer.py 序列化器
    from app01 import models
    from rest_framework import serializers
    
    class BookModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            fields = "__all__"
            
    # urls.py 路由
    from django.contrib import admin
    from django.urls import path,include
    from rest_framework.routers import SimpleRouter
    from app01 import views
    
    router = SimpleRouter()
    router.register('book',views.BookView)
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('',include(router.urls)),
    ]
    

    内置过滤类的使用

    1 在视图类views.py中(必须继承GenericAPIView)
    from app01 import models
    from app01 import serializer
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.filters import SearchFilter # 导入内置过滤类
    
    class BookView(ModelViewSet):
        queryset = models.Book.objects.all()
        serializer_class = serializer.BookModelSerializer
        # 配置过滤类(局部使用)
        filter_backends = [SearchFilter,]
        # 配置过滤字段
        search_fields = ['name','price']
        
        
    2 浏览的地址:
        # 查询的时候,所有条件都给search,并支持模糊匹配,search可以是name字段,也可以是price
        http://127.0.0.1:8000/book/?search=红楼梦
        http://127.0.0.1:8000/book/?search=123
                
    3 全局使用:在settings.py配置文件中配置
    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.SearchFilter',)
    }
    
    1944572-20220112112906686-1529595894.jpg

    第三方过滤类使用(django-filter)

    内置的SearchFilter过滤类,功能一般,如果你想实现更高级的过滤,自己写,使用第三方
    我们可以通过添加django-fitlter扩展来增强支持。

    1 安装(django:2.2, 3.1, 3.2)
        pip3 install django-filter
        
        
    2 在视图类views.py中(必须继承GenericAPIView)添加filter_fields属性,指定可以过滤的字段
    from app01 import models
    from app01 import serializer
    from rest_framework.viewsets import ModelViewSet
    from django_filters.rest_framework import DjangoFilterBackend # 导入第三方过滤类
    
    class BookView(ModelViewSet):
        queryset = models.Book.objects.all()
        serializer_class = serializer.BookModelSerializer 
    
        # 使用第三方
        # 配置过滤类(局部使用)
        filter_backends=[DjangoFilterBackend,]
        # 配置过滤字段
        filter_fields=['name','price']
        
    3 浏览的地址:
        # 查询可以通过字段查询,但不支持模糊查询
        http://127.0.0.1:8000/book/?price=123&name=红楼梦
       http://127.0.0.1:8000/book/?price=123
                  
            
    4 全局使用:在settings.py配置文件中配置
    
    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    }
    
    1.png

    自己定义过滤类

    1 写一个类,继承第三方过滤类(最好自定义一个py文件,filter.py)
    from rest_framework.filters import BaseFilterBackend
    
    
    class Filter(BaseFilterBackend):
        def filter_queryset(self, request, queryset, view):
            name = request.GET.get('name')
            queryset = queryset.filter(name__contains=name)
            return queryset
    
    
    2 在视图类views.py中配置
    from app01 import models
    from app01 import serializer
    from rest_framework.viewsets import ModelViewSet
    from app01.filter import Filter # 导入自定义过滤类
    class BookView(ModelViewSet):
        queryset = models.Book.objects.all()
        serializer_class = serializer.BookModelSerializer
         ## 自己定义的
        filter_backends = [Filter, ]
    
    
    3 浏览的地址:支持模糊查询
        http://127.0.0.1:8000/book/?name=红
    
    2.png

    总结

    1 APIViwe中有哪些类属性
        renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
        parser_classes = api_settings.DEFAULT_PARSER_CLASSES
        authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
        throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
        permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    2 GenericAPIView中有哪些类属性
        filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
    

    排序

    对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。
    使用方法:
    在类视图中设置filter_backends(排序本身也是过滤),使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。
    前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

    1 在views.py 视图类中
    from app01 import models
    from app01 import serializer
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.filters import OrderingFilter # 导入过滤器排序类
    
    class BookView(ModelViewSet):
        queryset = models.Book.objects.all()
        serializer_class = serializer.BookModelSerializer
        ###排序
        # 配置排序类(局部使用)
        filter_backends = [OrderingFilter, ] 
        # 配置排序字段
        ordering_fields=['name','price']
    
    
    2 请求方式:(postman中测试)
        http://127.0.0.1:8000/book/?ordering=price  # 默认升序
        http://127.0.0.1:8000/book/?ordering=-price  # 降序
        http://127.0.0.1:8000/book/?ordering=-price,-name # 配多个按,分隔
    
    
    3 全局使用:在settings.py 配置文件中配置
    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.OrderingFilter',),
    
    }
    
    3.png

    异常处理 Exceptions

    # 在views.py 视图类中写一个带错误的视图类
    from rest_framework.views import APIView
    
    class TestView(APIView):
    
        def get(self, request):
            a=[1,3,4]
            # 4/0
            print(a[100])
            return Response('test')
        
    # urls.py  路由
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('test/', views.TestView.as_view()),
      
    ]
    
    4.png

    REST framework 自定义异常处理

    1 手动创建一个名为exception的py文件,名字随意,在文件中写一个函数
    
    from rest_framework.views import exception_handler
    from rest_framework.response import Response
    
    def custom_exception_handler(exc, context):
        # 先调用REST framework默认的异常处理方法获得标准错误响应对象
        response=exception_handler(exc, context) 
        # 捕获异常后端窗口信息打印
        print(response) # 只要出错,这个就是None
        print(exc) # 错误信息在exc里
        print(context.get('view')) # 视图类
        print(context.get('request').get_full_path()) # 当次请求的request对象
        # 在此处补充自定义的异常处理
        if not response: # 更细粒度的对异常做一个区分
            if isinstance(exc,IndexError):
                response=Response({'status':5001,'msg':'越界异常'})
            elif isinstance(exc,ZeroDivisionError):
                response = Response({'status': 5002, 'msg': '越界异常'})
            else:
                response= Response({'status': 5000, 'msg': '没有权限'})
        # 在这可以记录日志:一旦出错就记录日志
        return response
    
    
    2 在settings.py 配置文件中配置
    REST_FRAMEWORK = {
         'EXCEPTION_HANDLER': 'app01.exception.custom_exception_handler',
    }
    
    
    3 以后只要视图中执行出了错误,就会捕获异常,记录日志,并返回统一的格式给前端
    
    5.png
    6.png

    REST framework定义的异常

    + APIException 所有异常的父类

    + ParseError 解析错误

    + AuthenticationFailed 认证失败

    + NotAuthenticated 尚未认证

    + PermissionDenied 权限决绝

    + NotFound 未找到

    + MethodNotAllowed 请求方式不支持

    + NotAcceptable 要获取的数据格式不支持

    + Throttled 超过限流次数

    + ValidationError 校验失败

    也就是说,很多的没有在上面列出来的异常,就需要我们在自定义异常中自己处理了。

    自动生成接口文档

    REST framework可以自动帮助我们生成接口文档。
    接口文档以网页的方式呈现。
    自动接口文档能生成的是继承自APIView及其子类的视图。

    接口文档 coreapi,swagger
    
    安装依赖:REST framewrok生成接口文档需要coreapi库的支持。
        pip3 install coreapi
     
    使用步骤:
    
    1 在urls.py 路由中
        from rest_framework.documentation import include_docs_urls
    
        urlpatterns = [
         path('doc/', include_docs_urls(title='图书管理项目接口文档')),
        ]
        
    2 在settings.py 配置文件中
        REST_FRAMEWORK = {
        'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
        }
        
    3 在view.py 视图类中对应的方法上加注释即可
        
    4 如果是ModelViewSet
       from app01 import models
        from app01 import serializer
        from rest_framework.viewsets import ModelViewSet
        from rest_framework.filters import OrderingFilter
    
    class BookView(ModelViewSet):
        """
          list:
          返回图书列表数据,通过Ordering字段排序
    
          retrieve:
          返回图书详情数据
    
          latest:
          返回最新的图书数据
    
          read:
          查询单个图书接口
        """
        queryset = models.Book.objects.all()
        serializer_class = serializer.BookModelSerializer
        # 排序
        filter_backends = [OrderingFilter,]
        ordering_fields = ['price','name']
        
        
    5 字段描述,写在models.py的help_text上
    from django.db import models
    
    class Book(models.Model):
        name = models.CharField(max_length=34,help_text='名字字段,字符串')
        price = models.IntegerField(help_text='价格字段,整型')
    
    6 浏览的地址(浏览器中)
        http://127.0.0.1:8000/doc/
                
    # 如果继承的是其它视图类,直接在对应的def函数下面写注释即可,例:
    class BookView(APIView):
        def get(self, request):
            """
            所有图书信息
            :param request: 
            :return: 
            """
            res = models.Book.objects.all()
            ser = serializer.BookModelSerializer(instance=res, many=True)
            return Response(ser.data)
    

    相关文章

      网友评论

          本文标题:drf 六

          本文链接:https://www.haomeiwen.com/subject/ewawcrtx.html