前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DRF框架学习(四)

DRF框架学习(四)

作者头像
小闫同学啊
发布2019-07-18 11:37:32
2.7K0
发布2019-07-18 11:37:32
举报
文章被收录于专栏:小闫笔记小闫笔记

DRF框架学习(四)

1.视图集对象的action属性

作用

获取现在要执行的是哪一种操作。

self.action:是字符串类型,目的是获取所有执行的操作。

使用场景

重写 get_serializer_class和get_queryset,根据不同的操作返回不同的序列化器类和不同的查询集。

def get_serializer_class(self):
    if self.action == 'list':
        # 返回list操作对应的序列化器类
    elif self.action == 'latest':
        # 返回latest操作对应的序列化器类
    else:
        # 返回其他操作对应的序列化器类

def get_queryset(self):
    if self.action == 'list':
        # 返回list操作所使用的查询集
    elif self.action == 'latest':
        # 返回latest操作所使用的查询集
    else:
        # 返回其他操作所使用的查询集

2.路由Router(urls文件中使用)

作用:(重点)

配合视图集进行使用,动态生成视图集中处理函数的url配置项。

使用:(重点)

1.创建router类的对象

from restframe_work.routers import SimpleRouter,DefaultRouter
router = SimpleRouter()或DefaultRouter()

2.注册视图集

router.register(prefix,viewset,base_name)

例如:

# 例如:
from booktest.views import BookInfoViewSet
router.register('books',views.BookInfoViewSet,base_name='books')

3.将生成的url配置项列表添加 urlpatterns中。

urlpatterns += router.urls

注意点

指定Router生成视图集处理函数url配置项时,提取的参数正则表达式。

lookup_value_regex = '\d+'

2.1视图集额外处理方法url配置项的生成

  • 需要给对应的方法添加action装饰器。
# detail为False 表示路径名格式应该为 books/latest/
    @action(methods=['get'], detail=False)
    def latest(self, request):
        """
  • 需要提取参数detail改为True,不需要提取参数的时候改为False
  • DefaultRouterSimpleRouter的区别是, DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。 DefaultRouter创建的对象,在访问url地址的时候,我们都可以在后面加一个 .json,那么后台会给我们返回json格式的数据。

3.案例

写一个视图集,提供一下两个接口

1.获取所有的图书信息 GET/books/list

2.获取指定的图书信息 GET/books/(?P\<pk>\d+)/retrieve

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import ReadOnlyModelViewSet

class BookInfoViewSet(ReadOnlyModelViewSet):
    # 指定当前视图所使用的查询集
    queryset = BookInfo.objects.all()
    # 指定当前视图所使用的序列化器类
    serializer_class = BookInfoSerializer
    # 指定当前视图所使用的认证类
    authentication_classes = [SessionAuthentication]
    # 指定当前视图所使用的权限控制类
    permission_classes = [IsAuthenticated]

url文件配置:

from restframe_work.routers import DefaultRouter
router = DefaultRouter()
from booktest.views import BookInfoViewSet
router.register('books',views.BookInfoViewSet,base_name='bookss')
urlpatterns += router.urls

4.认证

DRF框架默认设置了两种全局认证方案,session认证和基本认证。

全局认证就是针对我们所有的接口。

认证需要配合权限来使用

4.1使用

DRF框架的默认全局认证方案如下,可对其进行修改,比如注释掉基本认证:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',  # session认证
        'rest_framework.authentication.BasicAuthentication',   # 基本认证
    )
}

也可以在每个视图中通过设置authentication_classess属性来设置视图的认证方案:

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIView

class ExampleView(APIView):
    # 指定当前视图的认证方式(指定后不再使用全局的认证方案)
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    ...

配合权限,如果认证失败会有两种可能的返回值:

  • 401 Unauthorized 未认证
  • 403 Permission Denied 权限被禁止

5.权限

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
  • 在通过get_object()获取具体对象时,会进行对象访问权限的判断

DRF框架提供了四个权限控制类:

  • AllowAny允许所有用户(默认的)
  • IsAuthenticated仅通过认证的用户
  • IsAdminUser仅管理员用户
  • IsAuthenticatedOrReadOnly认证的用户可以完全操作,否则只能get读取

5.1使用

DRF框架的默认权限控制如下:

'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny', # 允许所有人
)

可以在配置文件中设置权限管理类,如:

REST_FRAMEWORK = {
    # 权限设置
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated', # 仅仅允许认证用户进行访问
    )
}

也可以在具体的视图中通过 permission_classes属性来指定某个视图所使用的权限控制类,如:

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

class ExampleView(APIView):
    #指定当前视图的权限控制类,指定以后不再使用全局设置
    permission_classes = [IsAuthenticated]
    # 还可以写成下面这个样子,但是注意逗号
    permission_classes = (IsAuthenticated,)
    ...

5.2自定义权限(了解即可)

如需自定义权限,需继承 rest_framework.permissions.BasePermission父类,并实现以下两个任何一个方法或全部

  • .has_permission(self,request,view)

是否可以访问视图, view表示当前视图对象

  • .has_object_permission(self,request,view,obj)

是否可以访问数据对象, view表示当前视图, obj为数据对象

例如:

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """判断对使用此权限类的视图是否有访问权限"""
        # 任何用户对使用此权限类的视图都有访问权限
        # True有权限,False没有权限
        return True

    def has_object_permission(self, request, view, obj):
        """判断对使用此权限类视图某个数据对象是否有访问权限"""
        # 需求: 对id为1,3的数据对象有访问权限,其他的对象没有访问权限
        if obj.id in (1, 3):
            return True
        return False

class BookInfoViewSet(ReadOnlyModelViewSet):
    # 指定当前视图所使用的查询集
    queryset = BookInfo.objects.all()
    # 指定当前视图所使用的序列化器类
    serializer_class = BookInfoSerializer
    # 指定当前视图所使用的认证类
    authentication_classes = [SessionAuthentication]
    # 使用自定义的权限控制类
    permission_classes = [MyPermission]

6.限流

作用:可以对接口访问的频次进行限制,以减轻服务器压力。

6.1 使用

DRF框架默认没有进行全局限流设置,但是提供了配置项,我们可以在配置文件中,使用 DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES进行全局配置。

6.1.1 可选限流类
6.1.1.1 AnonRateThrottle

限制所有匿名未认证用户,使用IP区分用户。

使用 DEFAULT_THROTTLE_RATES['anon'] 来设置频次

6.1.1.2 UserRateThrottle

限制认证用户,使用User id 来区分。

使用 DEFAULT_THROTTLE_RATES['user'] 来设置频次

6.1.1.3 ScopedRateThrottle

限制用户对于每个视图的访问频次,使用ip或user id。

6.1.2 限流设置
6.1.2.1针对匿名用户和认证用户分别进行限流控制
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        # 针对未登录(匿名)用户的限流控制类
        'rest_framework.throttling.AnonRateThrottle',
        # 针对登录(认证)用户的限流控制类
        'rest_framework.throttling.UserRateThrottle'
    ),
    # 指定限流频次
    'DEFAULT_THROTTLE_RATES': {
        # 认证用户的限流频次
        'user': '5/minutes',
        # 匿名用户的限流频次
        'anon': '3/minutes',
    },
}

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hourday来指明周期。

也可以在具体视图中通过throttle_classess属性来配置,如

from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class ExampleView(APIView):
    throttle_classes = [UserRateThrottle]
    ...
6.1.2.2针对匿名用户和认证用户进行统一的限流控制
REST_FRAMEWORK = {
    # 针对匿名用户和认证用户进行统一的限流控制
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle',
    ),

    # 设置限流频次选择项
    'DEFAULT_THROTTLE_RATES': {
        'upload': '3/minute',
        'contacts': '5/minute'
    },
}

进行了上面的配置之后,其实我们的视图还没有限流的效果,如果想实现限流,还需进行下列操作:

class ContactListView(APIView):
    # 指定限流频次选择项
    throttle_scope = 'contacts'
    ...
    pass


class UploadView(APIView):
    throttle_scope = 'uploads'
    ...
    pass

7.过滤

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

pip install django-filter

在配置文件中增加过滤后端的设置:

INSTALLED_APPS = [
    ...
    'django_filters',  # 需要注册应用,
]
# 过滤
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

在视图中添加filter_fields属性,指定可以过滤的字段

需求:写一个类视图,提供1个接口

1.获取所有的图书信息 GET/books/

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    # 指定过滤字段,根据书名和阅读量过滤,还可以添加其他的过滤字段
    filter_fields = ('btitle', 'bread')

# 127.0.0.1:8000/books/?btitle=西游记

8.排序

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

8.1使用方法:

在类视图中设置filter_backends,使用 rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

示例

默认是升序,如果想要实现降序的效果,那么在传入查询字符串的时候在字段名前加-,如下:

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    filter_backends = [OrderingFilter]
    # 根据指定字段进行排序
    ordering_fields = ('id', 'bread', 'bpub_date')
# 127.0.0.1:8000/books/?ordering=-bread

9.分页(重点)

REST framework提供了分页的支持。

我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  '<全局分页类>',
    'PAGE_SIZE': <页容量>  
}

如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5  # 每页数目
}

9.1可选分页类

9.1.1PageNumberPagination

?page=<页码>

前端访问网址形式:

GET  http://api.example.org/books/?page=4

可以在子类中定义的属性:

  • page_size 每页数目
  • pagequeryparam 前端发送的页数关键字名,默认为"page"
  • pagesizequery_param 前端发送的每页数目关键字名,默认为None
  • maxpagesize 前端最多能设置的每页数量
9.1.2LimitOffsetPagination

?offset=<偏移量>&limit=<数据条数>

前端访问网址形式:

GET http://api.example.org/books/?limit=100&offset=400

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与 PAGE_SIZE设置一直
  • limitqueryparam limit参数名,默认'limit'
  • offsetqueryparam offset参数名,默认'offset'
  • max_limit 最大limit限制,默认None

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

9.2自定义分页类

也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过 pagination_clas属性来指明。

class StandardResultPagination(PageNumberPagination):
    # 分页默认页容量
    page_size = 3
    # 获取分页数据时,传递也容量的参数名称
    page_size_query_param = 'page_size'
    # 分页时最大页容量,但是不能超过最大的页容量
    max_page_size = 5
class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    # 指定当前视图所使用的分页类
    pagination_class = StandardResultPagination

通过 http://api.example.org/books/?page=<页码>&page_size=<页容量> 进行访问。

注意:视图关闭分页

pagination_class = None

10.异常处理(重点)

REST framework提供了异常处理,可以出来以下异常:

  • APIException 所有异常的父类
  • ParseError 解析错误
  • AuthenticationFailed 认证失败
  • NotAuthenticated 尚未认证
  • PermissionDenied 权限决绝
  • NotFound 未找到
  • MethodNotAllowed 请求方式不支持
  • NotAcceptable 要获取的数据格式不支持
  • Throttled 超过限流次数
  • ValidationError 校验失败

10.1异常处理设置

DRF框架的默认异常处理设置如下:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

默认使用 rest_framework.views.exception_handler模块下的 exception_handler函数进行异常处理。

10.2自定义异常处理

10.2.1自定义DRF框架异常处理函数

1.自定义异常处理函数

2.设置EXCEPTION_HANDLER配置项

10.2.2详解

可以在DRF框架异常处理函数的基础上,补充一些其他的异常处理,比如数据库处理:

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseError

def exception_handler(exc, context):
    # 先调用DRF框架的默认异常处理函数
    response = drf_exception_handler(exc, context)

    if response is None:
        view = context['view']
        # 补充数据库的异常处理
        if isinstance(exc, DatabaseError):
            print('[%s]: %s' % (view, type(exc)))
            response = Response({'detail': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

在配置文件中声明自定义的异常处理:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'booktest.utils.exceptions.exception_handler'
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DRF框架学习(四)
    • 1.视图集对象的action属性
      • 2.路由Router(urls文件中使用)
        • 2.1视图集额外处理方法url配置项的生成
      • 3.案例
        • 4.认证
          • 4.1使用
        • 5.权限
          • 5.1使用
          • 5.2自定义权限(了解即可)
        • 6.限流
          • 6.1 使用
        • 7.过滤
          • 8.排序
            • 8.1使用方法:
          • 9.分页(重点)
            • 9.1可选分页类
            • 9.2自定义分页类
          • 10.异常处理(重点)
            • 10.1异常处理设置
            • 10.2自定义异常处理
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档