我们可以在settings.py文件中定义登录,权限,分页,异常等的全局配置,如下所示

REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'utils.page.Page',
'DEFAULT_AUTHENTICATION_CLASSES': (
'utils.permissions.AdminAuth',
),
'EXCEPTION_HANDLER': 'utils.custom_exception_handler.custom_exception_handler',
"DEFAULT_RENDERER_CLASSES":('rest_framework.renderers.JSONRenderer',),
'DATETIME_FORMAT': "%Y-%m-%d %H:%M",
# 'DEFAULT_PERMISSION_CLASSES': (
# 'utils.permissions.LoginPermission',
# )
}

也可以在对应的views,viewset中指定对应的class,来覆盖settings.py中的配置。

登录

drf 自己带了一个登录接口,在reset_framework.urls.py 里面,内容如下

urlpatterns = [
url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'), name='login'),
url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
]

其登录的用户是使用的django自己的User模块,登录方式为sessionid,相关信息存储在数据库中,登录的相关逻辑同admin中一致。

有时候,我们需要自己定义自己的登录用户模块,并在登录的时候,将user放到request.user 属性中,于是,我们可以编写自己的用户登录模块(具体的登录处理逻辑这里不做讨论,这里我们只看看怎么将我们的user model放到request.user中)

根据drf官方文档的例子,我们可以写出下面的代码

from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
"""获取META中的信息(也可以通过sessionid,token等在redis or mysql中查找),然后在model中取相应的用户,取出来,则返回对应的对象,没有,则返回None或则raise异常信息。返回的user对象会加载到requst的user属性,如果没有,则使用匿名用户"""
username = request.META.get('X_USERNAME')
if not username:
return None try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user') return (user, None)

可以发现,这一部分的工作仅仅是添加request.user属性,并没有对登录做权限的验证。

权限 permission

主要用于对接口权限的控制,比如知否具有该model,object的权限,是否登录,登录用户是否admin等限制条件。drf自带的权限验证有AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly, DjangoModelPermissions, DjangoModelPermissionsOrAnonReadOnly, DjangoObjectPermissions。我们也可以根据自己需要自己定义所需的权限验证类,如下

class Permission(permissions.BasePermission):

    def has_permission(self, request, view):
# docs文档接口不需要权限,因为真的online环境中没有docs的路由
if "docs" in request.path:
return True if getattr(request, "admin_login", None):
"""后台用户验证是否有权限"""
from precontract.views import CageView, PrecontractView, FosterView
from pet.views import PetView, ShapView, PetCategoryView # 根据view的类型,判断所需的权限名字
if isinstance(view, CageView) or isinstance(view, FosterView):
authority_name = "foster"
elif isinstance(view, PrecontractView):
authority_name = "precontract"
elif isinstance(view, PetView):
authority_name = "memeber"
else:
authority_name = "precontract" try:
user = request.user # 自己定义的user model
role = user.role
authority = Authority.objects.get(role=role, state='1')
authority_info = authority.get_info()
if authority_info[authority_name] != '1':
# 判断是否具有权限,返回False,则最终返回403状态,
# 而这里需要我们自定义处理的结果,所以raise一个自己写的异常
# return False
raise RightDenied
# 权限通过,返回True
return True
except BaseException:
raise RightDenied
# return False
raise PermissionDenied

异常处理

我们可以自己定义我们程序的异常的处理返回,或添加额外的返回信息,示例如下

import traceback
from rest_framework.views import exception_handler
from rest_framework.response import Response from django.http import HttpResponseRedirect import logging logger = logging.getLogger('views') def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# response = None # Now add the HTTP status code to the response.
# 捕获程序中的断言异常,作相关的处理,
if response is not None:
# raise exc
response.data['status_code'] = response.status_code
response.data['error'] = str(exc)
elif isinstance(exc, AssertionError):
# 断言错误,
response.data[‘detail’] = "断言错误"
response.data['error'] = str(exc)
else:
raise exc
return response

分页

示例如下

class CustomPagination(pagination.PageNumberPagination):
page_size = 20 # 默认分页大小
page_size_query_param = 'page_size' # 分页大小控制
max_page_size = 30 def get_paginated_response(self, data):
# 自定义分页后的数据返回格式
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'results': data
})

Django-rest-framework(五)自定义功能的更多相关文章

  1. django rest framework实现分页功能

    在web开发中很多需求都需要实现分页功能,然而 Django Rest Framework 自带的分页功能,只能在 mixins.ListModelMixin and generics.Generic ...

  2. Django REST framework 五种增删改查方法

    Django-DRF-视图的演变   版本一(基于类视图APIView类) views.py: APIView是继承的Django View视图的. 1 from .serializers impor ...

  3. Django admin有用的自定义功能

    引用园友 无名小妖 的博客 https://www.cnblogs.com/wumingxiaoyao/p/6928297.html 写的很好,但是博客园不能转载,不过我已经点赞了~

  4. Sentry 开发者贡献指南 - Django Rest Framework(Serializers)

    Serializer 用于获取复杂的 python 模型并将它们转换为 json.序列化程序还可用于在验证传入数据后将 json 反序列化回 Python 模型. 在 Sentry,我们有两种不同类型 ...

  5. Django REST framework+Vue 打造生鲜超市(五)

    六.商品类别数据展示 6.1. 商品类别数据接口 (1)商品分类有两个接口: 一种是全部分类:一级二级三级 一种是某一类的分类以及商品详细信息: 开始写商品分类的接口 (2)序列化 给分类添加三级分类 ...

  6. Django REST framework使用ViewSets的自定义路由实现过程

    在Django中使用基于类的视图(ClassView),类中所定义的方法名称与Http的请求方法相对应,才能基于路由将请求分发(dispatch)到ClassView中的方法进行处理,而Django ...

  7. 6 Django REST framework JWT 和登录功能实现

    JWT 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证. 我们不再使用Session认证机制,而使用Json Web Token认证机制. Json web token ( ...

  8. day71:drf:API接口&Restful API规范&Django Rest Framework&drf中的序列化和反序列化功能

    目录 1.web应用模式 2.API接口 3.Restful API规范 4.序列化 5.Django Rest Framework 1.drf的简单介绍 2.drf的特点 3.如何安装drf 4.d ...

  9. Django Rest Framework源码剖析(五)-----解析器

    一.简介 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数据格式,比如xml,所以需要解析这类数 ...

  10. Django REST framework 自定义(认证、权限、访问频率)组件

    本篇随笔在 "Django REST framework 初识" 基础上扩展 一.认证组件 # models.py class Account(models.Model): &qu ...

随机推荐

  1. Java学习第二十天

    1:递归(理解) (1)方法定义中调用方法本身的现象 举例:老和尚给小和尚讲故事,我们学编程 (2)递归的注意事项: A:要有出口,否则就是死递归 B:次数不能过多,否则内存溢出 C:构造方法不能递归 ...

  2. DistinctBy

    如何很好的使用Linq的Distinct方法[全屏看文] Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&q ...

  3. 新版本火狐 ,Chrome不支持showModalDialog解决办法

    平常的网站中,有时我们会希望使用者按下按钮后开启一个保持在原窗口前方的子窗口,在IE中,我们可以使用showModalDialog来达成,但是chrome早就不支持showModalDialog,最近 ...

  4. C#委托的好处

    C#委托的好处 先来看一个例子: 某人有三子,让他们各自带一样东西出门,并带回一头猎物. 可以理解为一种父亲对儿子的委托: 猎物  办法(工具 某工具) 三个人执行委托的方法各不相同 兔子 打猎(工具 ...

  5. ubuntu 下查找某个文件的方法

    1.whereis 文件名 特点:快速,但是是模糊查找,例如 找 #whereis mysql 它会把mysql,mysql.ini,mysql.*所在的目录都找出来. 2.find / -name  ...

  6. 基于ArcGIS的CAD数据向GIS数据转换方法(转)

    基于ArcGIS的CAD数据向GIS数据转换方法 1 CAD数据与ArcGIS数据介绍 地图数据来源多种多样,大多数使用的是计算机辅助设计软件(CAD)制作的数据,CAD软件制图自动化程度高,操作简单 ...

  7. 基本类型int强转short时发生了什么?

    我们知道java中一个int类型占32bits(4字节),一个short占16bits(2字节)强制转换时只取低16位(short类型占的那16位),高16位(去掉低位多出来的那部分)属于溢出不计算, ...

  8. Mantis去掉登录界面的“注册一个新账号”链接

    Mantis1.1.2主界面提供了新账号注册功能,但是只能注册默认权限的帐号.不是很实用,那就干脆去掉吧. (1) 打开Mantis目录下的login_page.php和lost_pwd_page.p ...

  9. PS软件怎么把视频转成gif动态图?

    PS软件怎么把视频转成gif动态图?Adobe PhotoShop软件的最新版本是可以编辑视频的,并且可以将视频转换为GIF动态图,使用也很简单,下面分享ps制作gif动态图的教程,需要的朋友可以参考 ...

  10. struts2+extjs文件上传完整实现(攻克了上传中的各种问题)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/shanhuhau/article/details/28617999 首先须要引入上传控件 <s ...