7. 分页组件/异常处理/自动生成接口文档/xadmin
本节内容:
三、
REST_FRAMEWORK = { # 全局分页,一旦设置了全局分页,那么我们drf中的视图扩展类里面的list方法提供的列表页都会产生分页的效果。所以一般不用全局分页 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 100 # 每页最大数据量 }
class LargeResultsSetPagination(PageNumberPagination): page_size = 1000 #127.0.0.1:8001/students/?page=5&page_size=10 page_size_query_param = 'page_size' max_page_size = 10000 class BookDetailView(RetrieveAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoSerializer pagination_class = LargeResultsSetPagination
注意:如果在视图内关闭分页功能,只需在视图内设置
pagination_class = None
前端访问网址形式:
GET http://127.0.0.1:8000/students/?page=4
-
page_size 每页数目
-
page_query_param 前端发送的页数关键字名,默认为"page"
-
page_size_query_param 前端发送的每页数目关键字名,默认为None
-
# 声明分页的配置类 from rest_framework.pagination import PageNumberPagination class StandardPageNumberPagination(PageNumberPagination): # 默认每一页显示的数据量 page_size = 2 # 允许客户端通过get参数来控制每一页的数据量 page_size_query_param = "size" max_page_size = 10 # 自定义页码的参数名 page_query_param = "p" class StudentAPIView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer pagination_class = StandardPageNumberPagination # 127.0.0.1/four/students/?p=1&size=5
前端访问网址形式:#其实就是通过偏移量来取数据
GET http://127.0.0.1/four/students/?limit=100&offset=400 #从下标为400的记录开始,取100条记录
-
default_limit 默认限制,每页数据量大小,默认值与
PAGE_SIZE
设置一致 -
limit_query_param limit参数名,默认'limit' , 可以通过这个参数来改名字
-
offset_query_param offset参数名,默认'offset' ,可以通过这个参数来改名字
-
from rest_framework.pagination import LimitOffsetPagination class StandardLimitOffsetPagination(LimitOffsetPagination): # 默认每一页查询的数据量,类似上面的page_size default_limit = 2 limit_query_param = "size" offset_query_param = "start" class StudentAPIView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer # 调用页码分页类 # pagination_class = StandardPageNumberPagination # 调用查询偏移分页类 pagination_class = StandardLimitOffsetPagination
REST framework提供了异常处理,我们可以自定义异常处理函数
写逻辑接口时,经常会出现错误,REST framework提供了异常处理,可以捕获接口错误,较少了代码冗余,此相当于中间件的功能
看一个简单的示例
class APIError(Exception): pass class Student2APIView(APIView): def get(self,request,pk): try: instance = Student.objects.get(pk=pk) except Student.DoesNotExist: raise APIError('自定义API错误') return Response({"message":"访问的商品已经下架~"}) serializer = StudentModelSerializer(instance=instance) return Response(serializer.data)
from rest_framework.views import exception_handler def custom_exception_handler(exc, context): #自定义的错误处理函数 """ exc错误对象 context 异常发生时的一些上下文信息 "”" # 先调用REST framework默认的异常处理方法获得标准错误响应对象 response = exception_handler(exc, context) #这个函数是drf提供的,它处理了一些错误,但是如果它处理不了的,它会返回None,所以,如果是None的话,我们需要自己来处理错误 # 在此处补充自定义的异常处理 if response is None: if isinstance(exc,APIError) #这里就可以记录错误信息了,一般记录到文件中,可以使用日志系统来进行记录 # return Respose({'msg':'自定义API错误了'}) response.data['status_code'] = response.status_code return response
在配置文件中还要声明自定义的异常处理
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler' }
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler' }
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): response = drf_exception_handler(exc, context) if response is None: view = context['view'] #出错的方法或者函数名称 if isinstance(exc, DatabaseError): print('[%s]: %s' % (view, exc)) response = Response({'detail': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE) return response
-
APIException 所有异常的父类
-
ParseError 解析错误
-
AuthenticationFailed 认证失败
-
NotAuthenticated 尚未认证
-
PermissionDenied 权限决绝
-
NotFound 未找到
-
MethodNotAllowed 请求方式不支持
-
NotAcceptable 要获取的数据格式不支持
-
Throttled 超过限流次数
-
ValidationError 校验失败
三、
接口文档以网页的方式呈现。
自动接口文档能生成的是继承自APIView
pip install coreapi
文档路由对应的视图配置为rest_framework.documentation.include_docs_urls
,
参数title
from rest_framework.documentation import include_docs_urls urlpatterns = [ ... path('docs/', include_docs_urls(title='站点页面标题')) ]
'AutoSchema' object has no attribute 'get_link'
REST_FRAMEWORK = { ... 'DEFAULT_SCHEMA_CLASS': "rest_framework.schemas.AutoSchema", }
1) 单一方法的视图,可直接使用类视图的文档字符串,如
class BookListView(generics.ListAPIView): """ get: 返回所有图书信息. post: 添加记录 """ #注意,这是在类中声明的注释,如果在方法中你声明了其他注释,会覆盖这个注释的
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(default=0, verbose_name='年龄', help_text='年龄') ...
或 注意,如果你多个应用使用同一个序列化器,可能会导致help_text的内容显示有些问题,小事情
class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student fields = "__all__" extra_kwargs = { 'age': { 'required': True, 'help_text': '年龄' } }
文档:https://xadmin.readthedocs.io/en/latest/index.html
GitHub地址:https://github.com/sshwsfc/django-xadmin
通过如下命令安装xadmin的最新版,它文档里面的安装方法好久没有更新了,会导致你安装不成功,所以我们使用下面的网址进行安装
pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2
在配置文件中注册如下应用
INSTALLED_APPS = [ ... 'xadmin', 'crispy_forms', 'reversion', ... ] # 修改使用中文界面 LANGUAGE_CODE = 'zh-Hans' # 修改时区 TIME_ZONE = 'Asia/Shanghai'
xadmin有建立自己的数据库模型类,需要进行数据库迁移
python manage.py makemigrations
python manage.py migrate
在总路由中添加xadmin的路由信息
import xadmin xadmin.autodiscover() # version模块自动注册需要版本控制的 Model from xadmin.plugins import xversion xversion.register_models() urlpatterns = [ path(r'xadmin/', xadmin.site.urls), ]
如果之前没有创建超级用户,需要创建,如果有了,则可以直接使用之前的。
python manage.py createsuperuser
-
-
xadmin的站点管理类不用继承
admin.ModelAdmin
,而是直接继承object
例如:在子应用中创建adminx.py文件。
import xadmin from xadmin import views class BaseSetting(object): """xadmin的基本配置""" enable_themes = True # 开启主题切换功能 use_bootswatch = True # 引导控制盘(其实就是我们的左侧菜单栏) xadmin.site.register(views.BaseAdminView, BaseSetting) class GlobalSettings(object): """xadmin的全局配置""" site_title = "路飞学城" # 设置站点标题 site_footer = "路飞学城有限公司" # 设置站点的页脚 menu_style = "accordion" # 设置菜单折叠 xadmin.site.register(views.CommAdminView, GlobalSettings)
xadmin可以使用的页面样式控制基本与Django原生的admin一直。
list_display = ['id', 'btitle', 'bread', 'bcomment']
search_fields = ['id','btitle']
list_filter = ['is_delete']
ordering = ['-age',] #-倒序
show_detail_fields = ['id',]
list_editable = ['name','age',]
refresh_times = [5, 10,30,60] # 设置允许后端管理人员按多长时间(秒)刷新页面,选好之后就能自动刷新了
list_export = ('xls', 'json','csv')#写元祖或者列表都行 list_export设置为None来禁用数据导出功能 list_export_fields = ('id', 'btitle', 'bpub_date') #设置允许导出的字段
show_bookmarks = True #False就隐藏了这个功能
data_charts = { "order_amount": { #随便写的名称order_amount 'title': '图书发布日期表', "x-field": "bpub_date", "y-field": ('btitle',), "order": ('id',), }, # 支持生成多个不同的图表 # "order_amount2": { # 'title': '图书发布日期表', # "x-field": "bpub_date", # "y-field": ('btitle',), # "order": ('id',) # }, }
-
-
x-field 控制x轴字段
-
y-field 控制y轴字段,可以是多个值
-
model_icon = 'fa fa-gift'
readonly_fields = ['name',]
这并不是所有功能,可以参看它的文档,它提供的一些功能我们可能还需要自定制,调整或者添加一些它没有的功能,后面再说