DRF-(8)

内容概览

  • 内置认证类、权限类、频率类
  • 补充django配置文件的配置说明
  • 过滤类的其他使用
  • 全局异常处理
  • 接口文档

内置认证类、权限类、频率类

内置的认证类

  • BasicAuthentication:此身份验证方案使用 HTTP 基本身份验证,该身份针对用户的用户名和密码进行了签名
  • RemoteUserAuthentication:通过此身份验证方案,可以将身份验证委派给Web服务器。
  • SessionAuthentication:通过session进行身份验证
  • TokenAuthentication:此身份验证方案使用简单的基于令牌的 HTTP 身份验证方案
    认证类建议自己写

内置权限类

  • AllowAny:直接返回True,允许所有
  • IsAuthenticated:只允许通过认证的用户访问
  • IsAdminUser:只允许管理员用户访问(user表中is_staff字段为True)

内置的频率类

  • AnonRateThrottle:通过ip地址限制,只需要在配置文件中配置’DEFAULT_THROTTLE_RATES’: { ‘anon’: ‘3/m’,}
  • UserRateThrottle:通过用户id限制,只需要在配置文件中配置’DEFAULT_THROTTLE_RATES’: { ‘user’: ‘3/m’,}

补充django配置文件的配置说明

import os


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 项目根路径
SECRET_KEY = '00s&54!s7c47gi(^97x!ep$ywfy8t3kj=%woay%u^cnhn^mqmz'  # 秘钥,自动生成的,django中涉及到加密的都需要使用到

DEBUG = True  # 是否为调试模式,开启可以在浏览器中看到错误信息,访问不存在的页面也会显示可访问的路由有哪些

ALLOWED_HOSTS = ['*']  # 允许项目部署的地址(后期项目上线,这里写服务器的地址),debug是False,这个必须加,不加就报错

INSTALLED_APPS = [  # 所有的app
    'django.contrib.admin',  # 后台管理admin
    'django.contrib.auth',  # 权限,6个表
    'django.contrib.contenttypes',
    'django.contrib.sessions',  # session认证相关
    'django.contrib.messages',  # 消息框架
    'django.contrib.staticfiles',  # 静态文件
    'app01.apps.App01Config',
    'rest_framework'
]

MIDDLEWARE = [  # 中间件
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',  # session相关
    'django.middleware.common.CommonMiddleware',  # 路由匹配不成功时把路由加/再匹配,如果添加后匹配成功,将该请求重定向到带/的地址
    'django.middleware.csrf.CsrfViewMiddleware',  # csrf相关
    'django.contrib.auth.middleware.AuthenticationMiddleware',  # 认证相关
    'django.contrib.messages.middleware.MessageMiddleware',  # 消息框架
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'drf_day08.urls'  # 根路由

TEMPLATES = [...]# 模板相关

WSGI_APPLICATION = 'drf_day08.wsgi.application'  # 后期项目项目上线,uwsgi运行这个application,测试阶段使用manage.py 运行项目

DATABASES = {  # 数据库相关
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

AUTH_PASSWORD_VALIDATORS = [...]  # auth的认证相关

# 国际化
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True

STATIC_URL = '/static/'  # 静态文件相关

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'  # 所有的自增主键都用BigAutoField

过滤类的其他使用

"""
内置的过滤类只能通过search=xxx搜索,不能够指定name=xxx&price=99
想要实现可以使用第三方模块或者自定义过滤类
"""
# 第三方:django-filter
1. pip install django-filter
2. 在视图类中配置:filter_backends = [DjangoFilterBackend]
3. 配置搜索的字段:filterset_fields = ['name', 'price']
4. 支持的搜索方式:http://127.0.0.1:8000/books/?name=红楼梦&price=99
5. 默认为精准搜索,条件使并且的关系

# 自定义过滤类
1. 写一个类,继承BaseFilterBackend
2. 重写filter_queryset方法
3. 在方法中过滤数据,并返回queryset对象
	    def filter_queryset(self, request, queryset, view):
        name = request.query_params.get('name')
        price = request.query_params.get('price')
        return queryset.filter(name__icontains=name,price__icontains=price)
4. 配置在视图类上:filter_backends = [类名]

"""多个过滤类和排序类可以共用,filter_backends=[],可以配置多个,执行顺序是从做往右,所以,放在最左侧的尽量先过滤掉大部分数据"""

全局异常处理

drf中无论在三大认证还是视图类的方法中执行,只要报错就会被捕获然后执行一个函数
DRF-(8)_第1张图片
只要出现异常被捕获了,就执行了drf中内置的配置文件中的配置:‘EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’,
只需要自己写一个函数,配置在配置文件中,以后出了异常,就会走我们写的函数

def exception_comment(exc, context):
	"""报错后记录日志"""
	request = context.get('request')  # 当此请求的request
    try:
        username = request.user.username
    except:
        username = '没有登录'
    ctime = time.time()
    path = request.path
    method_type = request.method
    print('%s用户,在%s时间,访问%s接口,通过%s请求访问,出了错误:%s' % (username, str(ctime), path, method_type, str(exc)))
    # 后期以上的代码要写到日志中
    response = exception_handler(exc, context)  # 内置的异常处理函数,只处理了drf自己的异常
    if response:  # 如果有值,说明是drf自己的异常,错误已经被处理了
        return Response({'code': 800, 'msg': 'drf错误:%s' % response.data.get("detail", "未知错误")})
    else:  # 如果没有值,说明不是drf的错误,是django或代码的错误
        return Response({'code': 900, 'msg': '系统错误:%s' % str(exc)})

# 在配置文件中配置
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'app01.views.exception_comment',}

接口文档

接口编写完成后,需要编写接口文档给前端的人使用
接口文档中一般需要有:请求地址、请求方式、支持的编码格式、请求参数、返回格式示例

  • 接口文档的写法有三种
    1. 直接使用Word或md写
    2. 使用接口文档平台,在接口文档平台录入(Yapi,第三方平台,自己开发接口文档平台)
    3. 项目自动生成:coreapi/swagger
      1. 下载coreapi模块:pip install coreapi
      2. 路由中配置
      from rest_framework.documentation import include_docs_urls
      urlpatterns = [
      path('docs/', include_docs_urls(title='接口文档')),
      ]
      3. 在配置文件中配置
      REST_FRAMEWORK = {
      'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
      }
      3. 在视图类中添加注释
      class BookView(ModelViewSet):
      """
      list:
          返回所有图书信息
      create:
          添加一本图书
      """
      """接口文档中的说明需要在序列化类中的字段属性help_text上添加"""
      

练习

  • 自定义一个过滤类,实现可以通过图书名或作者模糊匹配
from django.db.models import Q
from rest_framework.filters import BaseFilterBackend

class SearchFilter_app01(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        name = request.query_params.get('name', None)
        price = request.query_params.get('price', None)
        if name is None and price is None:
            return queryset
        elif name is None:
            return queryset.filter(Q(price__icontains=price))
        elif price is None:
            return queryset.filter(Q(name__icontains=name))
        return queryset.filter(Q(name__icontains=name) | Q(price__icontains=price))
  • 编写一个全局异常处理,让它生效
from rest_framework.views import exception_handler
from rest_framework.response import Response

def exception_comment(exc, context):
    response = exception_handler(exc, context)
    if response:
        return Response({'code': 800, 'msg': 'drf错误:%s' % response.data.get("detail", "未知错误")})
    else:
        return Response({'code': 900, 'msg': '系统错误:%s' % str(exc)})

你可能感兴趣的:(django,python,中间件)