能够在配置文件中配置全局默认的认证方案css
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', # session认证 'rest_framework.authentication.BasicAuthentication', # 基本认证 ) }
也能够在每一个视图中经过设置authentication_classess属性来设置html
from rest_framework.authentication import SessionAuthentication, BasicAuthentication from rest_framework.views import APIView class ExampleView(APIView): # 类属性 authentication_classes = [SessionAuthentication, BasicAuthentication] ...
认证失败会有两种可能的返回值:前端
401 Unauthorized 未认证python
403 Permission Denied 权限被禁止git
权限控制能够限制用户对于视图的访问和对于具体数据对象的访问。github
在执行视图的dispatch()方法前,会先进行视图访问权限的判断数据库
在经过get_object()获取具体对象时,会进行模型对象访问权限的判断django
能够在配置文件中全局设置默认的权限管理类,如json
REST_FRAMEWORK = { .... 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ) }
若是未指明,则采用以下默认配置bootstrap
'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.AllowAny', )
也能够在具体的视图中经过permission_classes属性来设置,如
from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView class ExampleView(APIView): permission_classes = (IsAuthenticated,) ...
AllowAny 容许全部用户
IsAuthenticated 仅经过认证的用户
IsAdminUser 仅管理员用户
IsAuthenticatedOrReadOnly 已经登录认证的用户能够对数据进行增删改操做,没有登录认证的只能查看数据。
from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework.generics import RetrieveAPIView class StudentAPIView(RetrieveAPIView): queryset = Student.objects.all() serializer_class = StudentSerializer authentication_classes = [SessionAuthentication] permission_classes = [IsAuthenticated]
如需自定义权限,需继承rest_framework.permissions.BasePermission父类,并实现如下两个任何一个方法或所有
.has_permission(self, request, view)
是否能够访问视图, view表示当前视图对象
.has_object_permission(self, request, view, obj)
是否能够访问数据对象, view表示当前视图, obj为数据对象
例如:
在当前子应用下,建立一个权限文件permissions.py中声明自定义权限类:
from rest_framework.permissions import BasePermission class IsXiaoMingPermission(BasePermission): def has_permission(self, request, view): if( request.user.username == "xiaoming" ): return True
from rest_framework.permissions import BasePermission class IsXiaoMingPermission(BasePermission): def has_permission(self, request, view): if( request.user.username == "xiaoming" ): return True
能够对接口访问的频次进行限制,以减轻服务器压力。
通常用于付费购买次数,投票等场景使用.
能够在配置文件中,使用DEFAULT_THROTTLE_CLASSES
和 DEFAULT_THROTTLE_RATES
进行全局配置,
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ), 'DEFAULT_THROTTLE_RATES': { 'anon': '100/day', 'user': '1000/day' } }
DEFAULT_THROTTLE_RATES
可使用 second
, minute
, hour
或day
来指明周期。
也能够在具体视图中经过throttle_classess属性来配置,如
from rest_framework.throttling import UserRateThrottle from rest_framework.views import APIView class ExampleView(APIView): throttle_classes = (UserRateThrottle,) ...
1) AnonRateThrottle
限制全部匿名未认证用户,使用IP区分用户。
使用DEFAULT_THROTTLE_RATES['anon']
来设置频次
2)UserRateThrottle
限制认证用户,使用User id 来区分。
使用DEFAULT_THROTTLE_RATES['user']
来设置频次
3)ScopedRateThrottle
限制用户对于每一个视图的访问频次,使用ip或user id。
例如:
class ContactListView(APIView): throttle_scope = 'contacts' ... class ContactDetailView(APIView): throttle_scope = 'contacts' ... class UploadView(APIView): throttle_scope = 'uploads' ... REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( 'rest_framework.throttling.ScopedRateThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'contacts': '1000/day', 'uploads': '20/day' } }
全局配置中设置访问频率
'DEFAULT_THROTTLE_RATES': { 'anon': '3/minute', 'user': '10/minute' }
from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework.generics import RetrieveAPIView from rest_framework.throttling import UserRateThrottle class StudentAPIView(RetrieveAPIView): queryset = Student.objects.all() serializer_class = StudentSerializer authentication_classes = [SessionAuthentication] permission_classes = [IsAuthenticated] throttle_classes = (UserRateThrottle,)
******用的不少
对于列表数据可能须要根据字段进行过滤,咱们能够经过添加django-fitlter扩展来加强支持。
pip install django-filter
在配置文件中增长过滤后端的设置:
INSTALLED_APPS = [ ... 'django_filters', # 须要注册应用, ] REST_FRAMEWORK = { ... 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
在视图中添加filter_fields属性,指定能够过滤的字段
class StudentListView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentSerializer filter_fields = ('age', 'sex') # 127.0.0.1:8000/four/students/?sex=1
对于列表数据,REST framework提供了OrderingFilter过滤器来帮助咱们快速指明数据按照指定字段进行排序。
使用方法:
在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter
过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,若是包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。
前端能够传递的ordering参数的可选字段值须要在ordering_fields中指明。
示例:
class StudentListView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer filter_backends = [OrderingFilter] ordering_fields = ('id', 'age') # 127.0.0.1:8000/books/?ordering=-age # -id 表示针对id字段进行倒序排序 # id 表示针对id字段进行升序排序
若是须要在过滤之后再次进行排序,则须要二者结合!
from rest_framework.generics import ListAPIView from students.models import Student from .serializers import StudentModelSerializer from django_filters.rest_framework import DjangoFilterBackend class Student3ListView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer filter_fields = ('age', 'sex') # 由于局部配置会覆盖全局配置,因此须要从新把过滤组件核心类再次声明, # 不然过滤功能会失效 filter_backends = [OrderingFilter,DjangoFilterBackend] ordering_fields = ('id', 'age')
REST framework提供了分页的支持。
咱们能够在配置文件中设置全局的分页方式,如:
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 100 # 每页数目 }
也可经过自定义Pagination类,来为视图添加不一样分页行为。在视图中经过pagination_clas
属性来指明。
class LargeResultsSetPagination(PageNumberPagination): page_size = 1000 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
1) PageNumberPagination
前端访问网址形式:
GET http://127.0.0.1:8000/students/?page=4
能够在子类中定义的属性:
page_size 每页数目
page_query_param 前端发送的页数关键字名,默认为"page"
page_size_query_param 前端发送的每页数目关键字名,默认为None
max_page_size 前端最多能设置的每页数量
# 声明分页的配置类 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
2)LimitOffsetPagination
前端访问网址形式:
GET http://127.0.0.1/four/students/?limit=100&offset=400
能够在子类中定义的属性:
default_limit 默认限制,默认值与PAGE_SIZE
设置一直
limit_query_param limit参数名,默认'limit'
offset_query_param offset参数名,默认'offset'
max_limit 最大limit限制,默认None
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提供了异常处理,咱们能够自定义异常处理函数。
from rest_framework.views import exception_handler def custom_exception_handler(exc, context): # 先调用REST framework默认的异常处理方法得到标准错误响应对象 response = exception_handler(exc, context) # 在此处补充自定义的异常处理 if response is None: response.data['status_code'] = response.status_code return response
在配置文件中声明自定义的异常处理
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler' }
若是未声明,会采用默认的方式,以下
rest_frame/settings.py 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 校验失败
也就是说,不少的没有在上面列出来的异常,就须要咱们在自定义异常中本身处理了。
REST framework能够自动帮助咱们生成接口文档。
接口文档以网页的方式呈现。
自动接口文档能生成的是继承自APIView
及其子类的视图。
REST framewrok生成接口文档须要coreapi
库的支持。
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='站点页面标题')) ]
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(default=0, verbose_name='年龄', help_text='年龄') ...
或
class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student fields = "__all__" extra_kwargs = { 'age': { 'required': True, 'help_text': '年龄' } }
xadmin是Django的第三方扩展,比使用Django的admin站点更强大也更方便。
文档:https://xadmin.readthedocs.io/en/latest/index.html
经过以下命令安装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再也不使用Django的admin.py,而是须要编写代码在adminx.py文件中。
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 控制列表展现的字段
list_display = ['id', 'btitle', 'bread', 'bcomment']
search_fields 控制能够经过搜索框搜索的字段名称,xadmin使用的是模糊查询
search_fields = ['id','btitle']
list_filter 能够进行过滤操做的列,对于分类、性别、状态
list_filter = ['is_delete']
ordering 默认排序的字段
show_detail_fields 在列表页提供快速显示详情信息
list_editable 在列表页能够快速直接编辑的字段
refresh_times 指定列表页的定时刷新
refresh_times = [5, 10,30,60] # 设置容许后端管理人员按多长时间(秒)刷新页面
list_export 控制列表页导出数据的可选格式
list_export = ('xls', 'xml', 'json') list_export设置为None来禁用数据导出功能 list_export_fields = ('id', 'btitle', 'bpub_date')
show_bookmarks 控制是否显示书签功能
show_bookmarks = True
data_charts 控制显示图表的样式
data_charts = { "order_amount": { 'title': '图书发布日期表', "x-field": "bpub_date", "y-field": ('btitle',), "order": ('id',) }, # 支持生成多个不一样的图表 # "order_amount": { # 'title': '图书发布日期表', # "x-field": "bpub_date", # "y-field": ('btitle',), # "order": ('id',) # }, }
title 控制图标名称
x-field 控制x轴字段
y-field 控制y轴字段,能够是多个值
order 控制默认排序
model_icon 控制菜单的图标【图标的设置能够参考bootstrap的图标css名称】
class BookInfoAdmin(object): model_icon = 'fa fa-gift' xadmin.site.register(models.BookInfo, BookInfodmin)
readonly_fields 在编辑页面的只读字段
exclude 在编辑页面隐藏的字段
ok