苏州网站建设企业网站制作,网站域名解析ip地址,用网站空间可以做有后台的网站吗,个人网站建设的小清新图片文章目录 1. 认证Authentication2. 权限Permissions使用提供的权限举例自定义权限 3. 限流Throttling基本使用可选限流类 4. 过滤Filtering5. 排序Ordering6. 分页Pagination可选分页器 7. 异常处理 ExceptionsREST framework定义的异常 8. 自动生成接口文档coreapi安装依赖设置… 文章目录 1. 认证Authentication2. 权限Permissions使用提供的权限举例自定义权限  3. 限流Throttling基本使用可选限流类  4. 过滤Filtering5. 排序Ordering6. 分页Pagination可选分页器 7. 异常处理 ExceptionsREST framework定义的异常  8. 自动生成接口文档coreapi安装依赖设置接口文档访问路径访问接口文档网页 yasg  为了方便接下来的学习我们创建一个新的子应用 opt python manage.py startapp opt注册子应用 
INSTALLED_APPS  [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,rest_framework,students,sers,    # 序列化器school,  # 序列化器嵌套req,     # 请求与响应demo,    # 视图opt,     # drf提供的组件使用
]总路由代码 
from django.contrib import admin
from django.urls import path, includeurlpatterns  [path(admin/, admin.site.urls),path(students/, include(students.urls)),path(sers/, include(sers.urls)),path(school/, include(school.urls)),path(req/, include(req.urls)),path(demo/, include(demo.urls)),path(opt/, include(opt.urls)),
] 
子路由代码 
from django.urls import path
from . import views
urlpatterns  []因为接下来的认证组件中需要使用到登陆功能所以我们使用django内置admin站点并创建一个管理员. 
admin运营站点的访问地址http://127.0.0.1:8000/admin 
python manage.py createsuperuser
# 如果之前有账号但是忘了可以通过终端下的命令修改指定用户的密码这里的密码必须8位长度以上的
python manage.py changepassword 用户名创建管理员以后访问admin站点先修改站点的语言配置 
settings.py 
LANGUAGE_CODE  zh-hansTIME_ZONE  Asia/Shanghai访问admin 站点效果 1. 认证Authentication 
可以在配置文件中配置全局默认的认证方案 
常见的认证方式cookie、session、token 
/site-packages/rest_framework/settings.py 默认配置文件 
REST_FRAMEWORK  {# 配置认证方式的选项DEFAULT_AUTHENTICATION_CLASSES: (rest_framework.authentication.SessionAuthentication, # session认证rest_framework.authentication.BasicAuthentication,   # basic认证)
}也可以在具体的视图类中通过设置authentication_classess类属性来设置单独的不同的认证方式 
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIViewclass ExampleView(APIView):# 类属性authentication_classes  [SessionAuthentication, BasicAuthentication]def get(self,request):pass认证失败会有两种可能的返回值这个需要我们配合权限组件来使用 
401 Unauthorized 未认证403 Permission Denied 权限被禁止 
自定义认证drfdemo.authentication代码 
from rest_framework.authentication import BaseAuthentication
from django.contrib.auth import get_user_modelclass CustomAuthentication(BaseAuthentication):自定义认证方式def authenticate(self, request):认证方法request: 本次客户端发送过来的http请求对象user  request.query_params.get(user)pwd   request.query_params.get(pwd)if user ! root or pwd ! houmen:return None# get_user_model获取当前系统中用户表对应的用户模型类user  get_user_model().objects.first()return (user, None)  # 按照固定的返回格式填写 用户模型对象, None视图调用自定义认证视图代码 
from django.contrib.auth.models import AnonymousUser
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication
from drfdemo.authentication import CustomAuthentication
# Create your views here.
class HomeAPIView(APIView):# authentication_classes  [CustomAuthentication, ]def get(self,request):单独设置认证方式print(request.user) # 在中间件AuthenticationMiddleware中完成用户身份识别的如果没有登录request.user值为AnonymousUserif request.user.id is None:return Response(未登录用户游客)else:return Response(f已登录用户{request.user})当然也可以注释掉上面视图中的配置改成全局配置。settings.py代码 
drf配置信息必须全部写在REST_FRAMEWORK配置项中
REST_FRAMEWORK  {# 配置认证方式的选项【drf的认证是内部循环遍历每一个注册的认证类一旦认证通过识别到用户身份则不会继续循环】DEFAULT_AUTHENTICATION_CLASSES: (drfdemo.authentication.CustomAuthentication,          # 自定义认证rest_framework.authentication.SessionAuthentication,  # session认证rest_framework.authentication.BasicAuthentication,    # 基本认证)
}2. 权限Permissions 
权限控制可以限制用户对于视图的访问和对于具有模型对象的访问。 
在执行视图的as_view()方法的dispatch()方法前会先进行视图访问权限的判断在通过get_object()获取具体模型对象时会进行模型对象访问权限的判断 
使用 
可以在配置文件settings中全局设置默认的权限管理类如 
REST_FRAMEWORK  {....DEFAULT_PERMISSION_CLASSES: (rest_framework.permissions.IsAuthenticated,)
}如果未指明则采用如下默认配置rest_framework/settings.py 
DEFAULT_PERMISSION_CLASSES: (rest_framework.permissions.AllowAny,
)也可以在具体的视图中通过permission_classes属性来进行局部设置如 
from django.contrib.auth.models import AnonymousUser
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication
from drfdemo.authentication import CustomAuthentication
# Create your views here.
from rest_framework.permissions import AllowAny,IsAuthenticated
class HomeAPIView(APIView):# authentication_classes  [CustomAuthentication, ]# permission_classes  [AllowAny]       # 如果项目中大部分视图接口不许直接访问少数接口可以直接访问则可以全局配置权限认证仅在部分不需要认证的视图类中加上AllowAny即可permission_classes  [IsAuthenticated]  # 如果项目中大部分视图接口允许直接访问少数接口必修认证权限则可以不要权限认证的全局配置仅在需要认证权限的视图下局部配置IsAuthenticated即可def get(self,request):单独设置认证方式print(request.user) # 在中间件AuthenticationMiddleware中完成用户身份识别的如果没有登录request.user值为AnonymousUserif request.user.id is None:return Response(未登录用户游客)else:return Response(f已登录用户{request.user})提供的权限 
AllowAny 允许所有用户默认权限IsAuthenticated 仅通过登录认证的用户IsAdminUser 仅管理员用户IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作没有登陆认证的只能查看数据。 
举例 
视图代码 
from rest_framework.viewsets import ModelViewSet
from school.models import Student
from school.serializers import StudentModelSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly
class Hom2APIView(ModelViewSet):authentication_classes  [CustomAuthentication, ]# 游客仅能查看数据登录用户可以进行数据的修改/添加/删除permission_classes  [IsAuthenticatedOrReadOnly]queryset  Student.objects.all()serializer_class  StudentModelSerializer路由代码 
from django.urls import path
from . import views
urlpatterns  [path(s1/, views.HomeAPIView.as_view()),
]from rest_framework.routers import DefaultRouter
router  DefaultRouter()
router.register(s2, views.Hom2APIView, s2)
urlpatterns  router.urls 
自定义权限 
如需自定义权限需继承rest_framework.permissions.BasePermission父类并实现以下两个任何一个方法或全部 .has_permission(self, request, view) 是否可以访问视图 view表示当前视图对象  .has_object_permission(self, request, view, obj) 是否可以访问模型对象 view表示当前视图 obj为模型数据对象  
例如 
在当前子应用下创建一个权限文件drfdemo.permissions.py中声明自定义权限类: 
from rest_framework.permissions import BasePermission
class IsXiaoMingPermission(BasePermission):自定义权限可用于全局配置也可以用于局部配置def has_permission(self, request, view):视图权限返回结果未True则表示允许访问视图类request: 本次客户端提交的请求对象view: 本次客户端访问的视图类# # 写在自己要实现认证的代码过程。# user  request.query_params.get(user)# # 返回值为True则表示通行# return user  xiaomingreturn Truedef has_object_permission(self, request, view, obj):模型权限写了视图权限(has_permission)方法一般就不需要写这个了。返回结果未True则表示允许操作模型对象from school.models import Studentif isinstance(obj, Student):# 限制只有小明才能操作Student模型user  request.query_params.get(user)return user  xiaoming  # 如果不是xiaoming返回值为False不能操作else:# 操作其他模型直接放行return True视图代码 
from rest_framework.viewsets import ModelViewSet
from school.models import Student
from school.serializers import StudentModelSerializer
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from drfdemo.permissions import IsXiaoMingPermission
class Hom2APIView(ModelViewSet):# authentication_classes  [CustomAuthentication, ]# 游客仅能查看数据登录用户可以进行数据的修改/添加/删除# permission_classes  [IsAuthenticatedOrReadOnly]# 自定义权限permission_classes  [IsXiaoMingPermission]queryset  Student.objects.all()serializer_class  StudentModelSerializer认证和权限的举例代码 
settings.py全局配置代码 
drf配置信息必须全部写在REST_FRAMEWORK配置项中
REST_FRAMEWORK  {# 配置认证方式的选项【drf的认证是内部循环遍历每一个注册的认证类一旦认证通过识别到用户身份则不会继续循环】DEFAULT_AUTHENTICATION_CLASSES: (# drfdemo.authentication.CustomAuthentication,          # 自定义认证rest_framework.authentication.SessionAuthentication,  # session认证rest_framework.authentication.BasicAuthentication,    # 基本认证),# 权限设置[全局配置在视图中可以通过permission_classes进行局部配置局部配置优先级高于全局配置]DEFAULT_PERMISSION_CLASSES: (# rest_framework.permissions.IsAuthenticated,drfdemo.permissions.IsXiaoMingPermission,),
}认证主要的作用就是识别客户端的访问者的身份但是不能拦截客户端的访问。 
权限是基于认证来实现的但是权限可以针对不同身份的用户进行拦截用户对视图、模型的访问操作。 
3. 限流Throttling 
可以对接口访问的频次进行限制以减轻服务器压力或者实现特定的业务。 
一般用于付费购买次数,投票等场景使用。 
基本使用 
可以在配置文件中使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置 
REST_FRAMEWORK  {# 限流全局配置# DEFAULT_THROTTLE_CLASSES:[ # 限流配置类#     rest_framework.throttling.AnonRateThrottle, # 未认证用户[未登录用户]#     rest_framework.throttling.UserRateThrottle, # 已认证用户[已登录用户]# ],DEFAULT_THROTTLE_RATES:{ # 频率配置anon: 2/day,  # 针对游客的访问频率进行限制实际上drf只是识别首字母但是为了提高代码的维护性建议写完整单词user: 5/day, # 针对会员的访问频率进行限制}
}DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day来指明周期。 
也可以在具体视图中通过throttle_classess属性来配置如 
from rest_framework.throttling import UserRateThrottle
class Student2ModelViewSet(ModelViewSet):queryset  Student.objectsserializer_class  StudentModelSerializer# 限流局部配置[这里需要配合在全局配置中的DEFAULT_THROTTLE_RATES来设置频率]throttle_classes  [UserRateThrottle]可选限流类 
1 AnonRateThrottle 
限制所有匿名未认证用户使用IP区分用户。【很多公司这样的IP结合设备信息来判断当然比IP要靠谱一点点而已】 
使用DEFAULT_THROTTLE_RATES[anon] 来设置频次 
2UserRateThrottle 
限制认证用户使用User模型的 id主键 来区分。 
使用DEFAULT_THROTTLE_RATES[user] 来设置频次 
3ScopedRateThrottle 
限制用户对于每个视图的访问频次使用ip或user id。 
settings.py代码 
drf配置信息必须全部写在REST_FRAMEWORK配置项中
REST_FRAMEWORK  {# 配置认证方式的选项【drf的认证是内部循环遍历每一个注册的认证类一旦认证通过识别到用户身份则不会继续循环】DEFAULT_AUTHENTICATION_CLASSES: (# drfdemo.authentication.CustomAuthentication,          # 自定义认证rest_framework.authentication.SessionAuthentication,  # session认证rest_framework.authentication.BasicAuthentication,    # 基本认证),# 权限设置[全局配置在视图中可以通过permission_classes进行局部配置局部配置优先级高于全局配置]DEFAULT_PERMISSION_CLASSES: (# rest_framework.permissions.IsAuthenticated,drfdemo.permissions.IsXiaoMingPermission,),# 限流全局配置DEFAULT_THROTTLE_CLASSES:[  # 限流配置类#     rest_framework.throttling.AnonRateThrottle,  # 未认证用户[未登录用户]#     rest_framework.throttling.UserRateThrottle,  # 已认证用户[已登录用户]rest_framework.throttling.ScopedRateThrottle,  # 基于自定义的命名空间来限流],DEFAULT_THROTTLE_RATES: {  # 频率配置anon: 1/s,  # 针对游客的访问频率进行限制实际上drf只是识别首字母但是为了提高代码的维护性建议写完整单词user: 1/s,  # 针对会员的访问频率进行限制Hom3: 3/m,  # 针对自定义命名空间进行限流}
}视图代码 
from rest_framework.throttling import AnonRateThrottle,UserRateThrottle
class Hom3APIView(APIView):# authentication_classes  [CustomAuthentication]  # 调用自定义认证# 局部配置限流# throttle_classes  [AnonRateThrottle, UserRateThrottle]# 配置自定义限流throttle_scope  Hom3   # 自定义命名空间[少用因为对于大部分的集体环境下都是公用一个IP地址]def get(self,request):return Response(f访问了视图)4. 过滤Filtering 
对于列表数据可能需要根据字段进行过滤我们可以通过添加django-fitlter扩展来增强支持。 
pip install django-filtersettings.py代码 
INSTALLED_APPS  [# ....django_filters,
]在配置文件中增加过滤器类的全局设置 
drf配置信息必须全部写在REST_FRAMEWORK配置项中
REST_FRAMEWORK  {# ....代码省略。。。# 过滤查询全局配置DEFAULT_FILTER_BACKENDS: [django_filters.rest_framework.DjangoFilterBackend],
}在视图类中添加类属性filter_fields指定可以过滤的字段 
class Hom4APIView(ModelViewSet):queryset  Student.objects.all()serializer_class  StudentModelSerializerfilter_fields  [sex,classmate]# list方法中进行调用-调用了GenericAPIView中声明的filter_queryset方法--- 配置中的过滤器类的filter_queryset--- filter_fields# 单个字段过滤
# http://127.0.0.1:8000/opt/s4/?classmate301
# http://127.0.0.1:8000/opt/s4/?sex1
# 多个字段过滤
# http://127.0.0.1:8000/opt/s4/?classmate502sex2路由代码 
from django.urls import path,include
from . import viewsfrom rest_framework.routers import DefaultRouter
router  DefaultRouter()
router.register(s2, views.Hom2APIView, s2)
router.register(s4, views.Hom4APIView, s4)urlpatterns  [path(s1/, views.HomeAPIView.as_view()),path(, include(router.urls)),  # 等价于  urlpatterns  router.urlspath(s3/, views.Hom3APIView.as_view()),path(s3/, views.Hom3APIView.as_view()),
]局部设置直接在视图中指定当前视图类中调用的过滤器类 
# 先注释掉settings中的全局过滤配置
from rest_framework.viewsets import ModelViewSet
from students.models import Student
from students.serializers import StudentModelSerializer
# Create your views here.
from django_filters.rest_framework import DjangoFilterBackend
class Hom4APIView(ModelViewSet):queryset  Student.objects.all()serializer_class  StudentModelSerializerfilter_backends  [DjangoFilterBackend, ]filter_fields  [sex,classmate]# list方法中进行调用-调用了GenericAPIView中声明的filter_queryset方法--- 配置中的过滤器类的filter_queryset--- filter_fields5. 排序Ordering 
对于列表数据REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。 
使用方法 
在类视图中设置filter_backends使用rest_framework.filters.OrderingFilter过滤器REST framework会在请求的查询字符串参数中检查是否包含了ordering参数如果包含了ordering参数则按照ordering参数指明的排序字段对数据集进行排序。 
前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。 
配置文件settings.py代码 
drf配置信息必须全部写在REST_FRAMEWORK配置项中
REST_FRAMEWORK  {# 。。。代码省略# 过滤查询全局配置# 过滤和排序使用了一个公用的配置项所以2个组件要么一起全局配置要么就一起局部配置DEFAULT_FILTER_BACKENDS: [#     django_filters.rest_framework.DjangoFilterBackend,  # 过滤rest_framework.filters.OrderingFilter,  # 排序],
}视图代码 
from rest_framework.viewsets import ModelViewSet
from students.models import Student
from students.serializers import StudentModelSerializer
# Create your views here.
from django_filters.rest_framework import DjangoFilterBackend
class Hom4APIView(ModelViewSet):queryset  Student.objects.all()serializer_class  StudentModelSerializer# 局部过滤# filter_backends  [DjangoFilterBackend, OrderingFilter]# 过滤字段# filter_fields  [sex,classmate]# 数据排序ordering_fields  [id, age]# 127.0.0.1:8000/books/?ordering-age
# -id 表示针对id字段进行倒序排序
# id  表示针对id字段进行升序排序上面提到因为过滤和排序公用了一个配置项所以排序和过滤要一起使用则必须整个项目要么一起全局过滤排序要么一起局部过滤排序。决不能出现一个全局一个局部的这种情况局部会覆盖全局的配置。 
from rest_framework.viewsets import ModelViewSet
from students.models import Student
from students.serializers import StudentModelSerializer
# Create your views here.
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
class Hom4APIView(ModelViewSet):queryset  Student.objects.all()serializer_class  StudentModelSerializer# 局部过滤filter_backends  [DjangoFilterBackend, OrderingFilter]# 过滤字段filter_fields  [sex,classmate]# list方法中进行调用-调用了GenericAPIView中声明的filter_queryset方法--- 配置中的过滤器类的filter_queryset--- filter_fields# 数据排序ordering_fields  [id, age]# http://127.0.0.1:8000/opt/demo4/?orderingidclassmate3016. 分页Pagination 
因为django默认提供的分页器主要使用于前后端不分离的业务场景所以REST framework也提供了分页的支持。 
我们可以在配置文件中设置全局的分页方式如 
REST_FRAMEWORK  {# 分页全局配置# 页码分页器  ?page页码page_size单页数据量# DEFAULT_PAGINATION_CLASS:  rest_framework.pagination.PageNumberPagination,# 偏移量分页器 ?limit单页数据量offset数据开始下标DEFAULT_PAGINATION_CLASS:  rest_framework.pagination.LimitOffsetPagination,PAGE_SIZE: 10  # 每页数目如果不设置则没有进行分配
}# 如果在settings.py配置文件中 设置了全局分页那么在drf中凡是调用了ListModelMixin的list()都会自动分页。如果项目中出现大量需要分页的数据只有少数部分的不需要分页则可以在少部分的视图类中关闭分页功能。
# 另外视图类在使用过分页以后务必在编写queryset属性时模型.objects后面调用结果。例如
# Student.objects.all()
class Hom5APIView(ListAPIView):pagination_class  None也可通过自定义Pagination类来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。 
可选分页器 
1 PageNumberPagination 
前端访问网址形式 
GET  http://127.0.0.1:8000/students/?page4可以在子类中定义的属性 
page_size 每页数目page_query_param 前端发送的页数关键字名默认为pagepage_size_query_param 前端发送的每页数目关键字名默认为Nonemax_page_size 前端最多能设置的每页数量 
分页器类paginations代码 
from  rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
# PageNumberPagination以页码作为分页条件
# page1page_size10      第1页
# page2page_size10      第2页
# ...
# LimitOffsetPagination以数据库查询的limit和offset数值作为分页条件
# limit10offset0   第1页
# limit10offset10  第2页
# ...# 自定义分页器PageNumberPagination
class StudentPageNumberPagination(PageNumberPagination):page_query_param  page # 查询字符串中代表页码的变量名page_size_query_param  size # 查询字符串中代表每一页数据的变量名page_size  2 # 每一页的数据量max_page_size  4 # 允许客户端通过查询字符串调整的最大单页数据量视图views 代码 from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination# 分页类往往会单独的保存到一个独立的模块例如当前子应用目录下创建一个pagination.py保存使用时导包
class Hom5PageNumberPagination(PageNumberPagination):page_size  10                  # 默认分页的每一页数据量max_page_size  20              # 设置允许客户端通过地址栏参数调整的最大单页数据量page_query_param  pn         # 地址栏上代表页码的变量名默认是 pagepage_size_query_param  size  # 地址栏上代表单页数据量的变量名默认是page_sizeclass Hom5APIView(ModelViewSet):# queryset  Student.objects  # 这句话在没有进行分页时不会报错调用了分页则会报错queryset  Student.objects.all()serializer_class  StudentModelSerializer# 局部分页# pagination_class  None  # 关闭分页功能# 局部分页往往采用自定义分页类进行分页数据量的配置pagination_class  Hom5PageNumberPaginationdef list(self, request, *args, **kwargs):# 获取django的配置项from django.conf import settings# 获取rest_framework的配置项# from rest_framework.settings import api_settings# print(api_settings.DEFAULT_PAGINATION_CLASS)return super().list(request, *args, **kwargs)2LimitOffsetPagination 
前端访问网址形式 
GET http://127.0.0.1/four/students/?limit100offset100可以在子类中定义的属性 
default_limit 默认限制默认值与PAGE_SIZE设置一直limit_query_param limit参数名默认’limit’offset_query_param offset参数名默认’offset’max_limit 最大limit限制默认None 
分页类代码 
from  rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
# PageNumberPagination以页码作为分页条件
# page1size10      第1页
# page2size10      第2页
# LimitOffsetPagination以数据库查询的limit和offset数值作为分页条件
# limit10offset0   第1页
# limit10offset10  第2页# LimitOffsetPagination
class StudentLimitOffsetPagination(LimitOffsetPagination):limit_query_param  limit # 查询字符串中代表每一页数据的变量名offset_query_param  offset # 查询字符串中代表页码的变量名default_limit  2 # 每一页的数据量max_limit  4 # 允许客户端通过查询字符串调整的最大单页数据量视图views代码 
from .paginations import StudentPageNumberPagination,StudentLimitOffsetPagination
class Student3ModelViewSet(ModelViewSet):queryset  Student.objects.all()serializer_class  StudentModelSerializer# 取消当前视图类的分页效果# pagination_class  None# 局部分页pagination_class  StudentLimitOffsetPagination7. 异常处理 Exceptions 
REST framework本身在APIView提供了异常处理但是仅针对drf内部现有的接口开发相关的异常进行格式处理但是开发中我们还会使用到各种的数据或者进行各种网络请求这些都有可能导致出现异常这些异常在drf中是没有进行处理的所以就会冒泡给django框架了django框架会进行组织错误信息作为html页面返回给客户端所在在前后端分离项目中可能js无法理解或者无法接收到这种数据甚至导致js出现错误的情况。因此为了避免出现这种情况我们可以自定义一个属于自己的异常处理函数对于drf无法处理的异常我们自己编写异常处理的代码逻辑。 
针对于现有的drf的异常处理进行额外添加属于开发者自己的逻辑代码一般我们编写的异常处理函数会写一个公共的目录下或者主应用目录下。这里主应用下直接创建一个excepitions.py代码 
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
# 针对mysql、mongoDB、redis、第三方数据接口
def custom_exception_handler(exc, context):自定义异常函数exc: 异常实例对象发生异常时实例化出来的context: 字典异常发生时python解释器收集的执行上下文信息。所谓的执行上下文就是python解释器在执行代码时保存在内存中的变量、函数、类、对象、模块等一系列的信息组成的环境信息。response  exception_handler(exc, context)if response is None:当前异常drf无法处理if isinstance(exc, ZeroDivisionError):response  Response({detail:数学老师还有30秒达到战场0不能作为除数}, statusstatus.HTTP_500_INTERNAL_SERVER_ERROR)return response在配置文件中声明自定义的异常处理settings代码 
REST_FRAMEWORK  {# 异常配置EXCEPTION_HANDLER: drfdemo.exceptions.custom_exception_handler
}如果未声明自定义异常的话drf会采用默认的方式使用自己封装的异常处理函数rest_frame/settings.py 
REST_FRAMEWORK  {EXCEPTION_HANDLER: rest_framework.views.exception_handler
}例如 
补充上处理关于数据库的异常这里使用其他异常来举例 
主应用.exceptions代码 
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
from django.db import DatabaseError
# 针对mysql、mongoDB、redis、第三方数据接口
def custom_exception_handler(exc, context):自定义异常函数exc: 异常实例对象发生异常时实例化出来的context: 字典异常发生时python解释器收集的执行上下文信息。所谓的执行上下文就是python解释器在执行代码时保存在内存中的变量、函数、类、对象、模块等一系列的信息组成的环境信息。response  exception_handler(exc, context)print(fcontext{context})if response is None:当前异常drf无法处理view  context[view] # 获取异常发生时的视图类request  context[request] # 获取异常发生时的客户端请求对象if isinstance(exc, ZeroDivisionError):response  Response({detail:数学老师还有30秒达到战场0不能作为除数}, statusstatus.HTTP_500_INTERNAL_SERVER_ERROR)if isinstance(exc, TypeError):print([%s]: %s % (view, exc))response  Response({detail: 服务器内部错误}, statusstatus.HTTP_500_INTERNAL_SERVER_ERROR)return response视图中故意报错 
from rest_framework.pagination import LimitOffsetPagination, PageNumberPaginationclass Hom5PageNumberPagination(PageNumberPagination):page_size  10                  # 默认分页的每一页数据量max_page_size  20              # 设置允许客户端通过地址栏参数调整的最大单页数据量page_query_param  pn         # 地址栏上代表页码的变量名默认是 pagepage_size_query_param  size  # 地址栏上代表单页数据量的变量名默认是page_sizeclass Hom5APIView(ModelViewSet):queryset  Student.objects  # 这句话在没有进行分页时不会报错调用了分页则会报错所以会进入异常处理# queryset  Student.objects.all()serializer_class  StudentModelSerializer# 局部分页# pagination_class  None  # 关闭分页功能# 局部分页往往采用自定义分页类进行分页数据量的配置pagination_class  Hom5PageNumberPaginationdef list(self, request, *args, **kwargs):# 获取django的配置项from django.conf import settings# 获取rest_framework的配置项# from rest_framework.settings import api_settings# print(api_settings.DEFAULT_PAGINATION_CLASS)return super().list(request, *args, **kwargs)REST framework定义的异常 
APIException 所有异常的父类ParseError 解析错误AuthenticationFailed 认证失败NotAuthenticated 尚未认证PermissionDenied 权限拒绝NotFound 404 未找到MethodNotAllowed 请求方式不支持NotAcceptable 要获取的数据格式不支持Throttled 超过限流次数ValidationError 校验失败 
也就是说很多的没有在上面列出来的异常就需要我们在自定义异常中自己处理了。 
8. 自动生成接口文档 
REST framework可以自动帮助我们生成接口文档。 
接口文档以网页的方式呈现。 
自动接口文档能生成的是继承自APIView及其子类的视图。 
coreapi 
安装依赖 
REST framewrok生成接口文档需要coreapi库的支持。 
pip install coreapi设置接口文档访问路径 
在总路由中添加接口文档路径。 
文档路由对应的视图配置为rest_framework.documentation.include_docs_urls 
参数title为接口文档网站的标题。总路由urls.py代码 
from rest_framework.documentation import include_docs_urlsurlpatterns  [...path(docs/, include_docs_urls(title站点页面标题))
]在settings.py中配置接口文档。 
INSTALLED_APPS  [coreapi,]
REST_FRAMEWORK  {# 。。。 其他选项# 接口文档DEFAULT_SCHEMA_CLASS: rest_framework.schemas.AutoSchema,
}8.3. 文档描述说明的定义位置 
1 单一方法的视图可直接使用类视图的文档字符串如 
class BookListView(generics.ListAPIView):返回所有图书信息2包含多个方法的视图在类视图的文档字符串中分开方法定义如 
class BookListCreateView(generics.ListCreateAPIView):get:返回所有图书信息.post:新建图书.3对于视图集ViewSet仍在类视图的文档字符串中封开定义但是应使用action名称区分如 
class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):list:返回图书列表数据retrieve:返回图书详情数据latest:返回最新的图书数据read:修改图书的阅读量访问接口文档网页 
浏览器访问 127.0.0.1:8000/docs/即可看到自动生成的接口文档。 两点说明 
1 视图集ViewSet中的retrieve名称在接口文档网站中叫做read 
2参数的Description需要在模型类或序列化器类的字段中以help_text选项定义如 
class Student(models.Model):...age  models.IntegerField(default0, verbose_name年龄, help_text年龄)...或 
class StudentSerializer(serializers.ModelSerializer):class Meta:model  Studentfields  __all__extra_kwargs  {age: {required: True,help_text: 年龄}}yasg 
安装 
pip install drf-yasg配置settings.py代码 
INSTALLED_APPS  [drf_yasg,  # 接口文档drf_yasg]总路由 
from django.contrib import admin
from django.urls import path, include
from rest_framework.documentation import include_docs_urls# yasg的视图配置类用于生成api
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view  get_schema_view(openapi.Info(titledrf接口文档,  # 必传default_versionv1.0,0,  # 必传description描述信息,terms_of_service,contactopenapi.Contact(email649641514qq.com),licenseopenapi.License(name协议版本)),publicTrue,# permission_classes(rest_framework.permissions.AllowAny)  # 权限类
)urlpatterns  [# 文档路由path(doc/, schema_view.with_ui(swagger, cache_timeout0), nameschema-swagger),path(docs/, include_docs_urls(title站点页面标题)),path(admin/, admin.site.urls),path(students/, include(students.urls)),path(sers/, include(sers.urls)),path(school/, include(school.urls)),path(req/, include(req.urls)),path(demo/, include(demo.urls)),path(opt/, include(opt.urls)),
] 
http://127.0.0.1:8000/doc/访问效果