drf 六

目录

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)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341

推荐阅读更多精彩内容