1. 需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员。
python manage.py createsuperuser
2. 配置 settings.py
1.站点语言配置:
# LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' # 配置中文
开始
(1)可以在配置文件中配置全局默认的认证方案:
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类 'rest_framework.renderers.JSONRenderer', # json渲染器 'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器 ), # 认证数据的记录方式 'DEFAULT_AUTHENTICATION_CLASSES': ( # 这里我们会加上jwt 'rest_framework.authentication.BasicAuthentication', # 基本认证 'rest_framework.authentication.SessionAuthentication', # session认证 ),}
(2)也可以在每个视图中通过设置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 权限被禁止
2. 权限Permissions
权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。
-
在执行视图的dispatch()方法前,会先进行视图访问权限的判断
-
在通过get_object()获取具体对象时,会进行模型对象访问权限的判断
使用
1.可以在配置文件中设置默认的权限管理类,如
# 权限管理类
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
如果未指明,则采用如下默认配置,在REST_FRAMEWORK ={}中:
'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.AllowAny', )
2.也可以在具体的视图中通过permission_classes属性来设置,views.py 中:from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet from book.models import Book from .serializers import BookModelSerializer # 用户认证 from rest_framework.authentication import BaseAuthentication,SessionAuthentication # 权限 from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import BasePermission # 自定义权限 ,必须继承 BasePermission class CustomPermission(BasePermission): def has_permission(self, request, view): # 当前权限方法用于判断访问者是否有权限访问对应的视图 # 获取当前已经登录的用户可以用request.user return request.user.username=='wang' # 返回的是布尔值
# 视图: class BookModelSetView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookModelSerializer # 只是设置了认证方式,还需要结合权限来 ,这里会报错, .authenticate() must be overridden. #authentication_classes = [SessionAuthentication,BaseAuthentication] # 权限 # permission_classes = [IsAuthenticated] permission_classes = [CustomPermission]
提供的权限
-
AllowAny 允许所有用户
-
IsAuthenticated 仅通过认证的用户
-
IsAdminUser 仅管理员用户
-
IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。
自定义权限
如需自定义权限,需继承rest_framework.permissions.BasePermission父类,并实现以下两个任何一个方法或全部
-
has_permission(self, request, view)
是否可以访问视图, view表示当前视图对象
-
.has_object_permission(self, request, view, obj)
是否可以访问数据对象, view表示当前视图, obj为数据对象
例如:
class MyPermission(BasePermission): def has_object_permission(self, request, view, obj): """控制对obj对象的访问权限,此案例决绝所有对对象的访问""" return False class BookInfoViewSet(ModelViewSet): queryset = BookInfo.objects.all() serializer_class = BookInfoSerializer permission_classes = [IsAuthenticated, MyPermission]
3. 限流Throttling
可以对接口访问的频次进行限制,以减轻服务器压力。
使用
1. 可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES
和 DEFAULT_THROTTLE_RATES
进行全局配置,
REST_FRAMEWORK = {
# 限流
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',# 普通用户
'rest_framework.throttling.UserRateThrottle' # 登录用户
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/day', # 一天只能访问3次
'user': '5/day' # 一天只能访问5次
},
}
DEFAULT_THROTTLE_RATES
可以使用 second
, minute
, hour
或day
来指明周期。
2.也可以在具体视图中通过throttle_classess属性来配置,如
from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from book.models import Book from .serializers import BookModelSerializer # 限流 from rest_framework.throttling import AnonRateThrottle,UserRateThrottle class BookModelSetView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookModelSerializer # 限流 throttle_classes = [AnonRateThrottle,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' } }
4. 过滤Filtering
对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。
pip install django-filter
1.在配置文件中增加过滤后端的设置:
1.注册应用:
INSTALLED_APPS = [ 'django_filters', # 需要注册应用, ]
2.配置
# drf框架的配置字典,所以关于drf的配置信息,要记录在这里即可。 REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), }
在视图中添加filter_fields属性,指定可以过滤的字段
访问时:127.0.0.1:8000/books/?btitle=西游记
from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from book.models import Book from .serializers import BookModelSerializer # 过滤排序 from rest_framework.filters import OrderingFilter class BookModelSetView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookModelSerializer # 过滤 filter_fields = ('title', 'bread')
5. 排序
对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。
使用方法:
在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter
过滤器,
REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,
则按照ordering参数指明的排序字段对数据集进行排序。
前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。
示例:
# 127.0.0.1:8000/books/?ordering=-bread
from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from book.models import Book from .serializers import BookModelSerializer # 过滤排序 from rest_framework.filters import OrderingFilter class BookModelSetView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookModelSerializer # 过滤 filter_fields = ('title', 'bread') # 过滤排序 filter_backends = [OrderingFilter] OrderingFilter=['id','bread','bcommnet']
6. 分页Pagination
REST framework提供了分页的支持。
1.可以在配置文件中设置全局的分页方式,如:
# drf框架的配置字典,所以关于drf的配置信息,要记录在这里即可。 REST_FRAMEWORK = { # 分页配置[全局配置,针对整个项目所有列表视图都会产生分页效果] 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 2, # 每页数目 }
2.也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas
属性来指明。
from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from book.models import Book from .serializers import BookModelSerializer # 自定义分页器 from rest_framework.pagination import PageNumberPagination class BookPageNumberPagination(PageNumberPagination): page_size = 3 max_page_size = 10 page_query_param = 'page_size' ## http;//loclahost/?page_size=5 class BookModelSetView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookModelSerializer # 分页 # 指定当前视图类的列表视图[局部配置] # pagination_class = BookPageNumberPagination pagination_class = None # 阻止全局的分页配置给当前的列表视图生成分页效果
注意:如果在视图内关闭分页功能,只需在视图内设置
pagination_class = None
可选分页器
1) PageNumberPagination
前端访问网址形式:
GET http://api.example.org/books/?page=4
可以在子类中定义的属性:
-
page_size 每页数目
-
page_query_param 前端发送的页数关键字名,默认为"page"
-
page_size_query_param 前端发送的每页数目关键字名,默认为None
-
max_page_size 前端最多能设置的每页数量
view.py 视图中:
from rest_framework.pagination import PageNumberPagination class StandardPageNumberPagination(PageNumberPagination): page_size_query_param = 'page_size' max_page_size = 10 class BookListView(ListAPIView): queryset = BookInfo.objects.all().order_by('id') serializer_class = BookInfoSerializer pagination_class = StandardPageNumberPagination # 127.0.0.1/books/?page=1&page_size=2
2)LimitOffsetPagination
前端访问网址形式:
GET http://api.example.org/books/?limit=100&offset=400
可以在子类中定义的属性:
-
default_limit 默认限制,默认值与
PAGE_SIZE
设置一直 -
limit_query_param limit参数名,默认'limit'
-
offset_query_param offset参数名,默认'offset'
-
max_limit 最大limit限制,默认None