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

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_PAGINATION_CLASS': 'utils.page.Page',
  3. 'DEFAULT_AUTHENTICATION_CLASSES': (
  4. 'utils.permissions.AdminAuth',
  5. ),
  6. 'EXCEPTION_HANDLER': 'utils.custom_exception_handler.custom_exception_handler',
  7. "DEFAULT_RENDERER_CLASSES":('rest_framework.renderers.JSONRenderer',),
  8. 'DATETIME_FORMAT': "%Y-%m-%d %H:%M",
  9. # 'DEFAULT_PERMISSION_CLASSES': (
  10. # 'utils.permissions.LoginPermission',
  11. # )
  12. }

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

登录

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

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

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

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

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

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

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

权限 permission

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

  1. class Permission(permissions.BasePermission):
  2. def has_permission(self, request, view):
  3. # docs文档接口不需要权限,因为真的online环境中没有docs的路由
  4. if "docs" in request.path:
  5. return True
  6. if getattr(request, "admin_login", None):
  7. """后台用户验证是否有权限"""
  8. from precontract.views import CageView, PrecontractView, FosterView
  9. from pet.views import PetView, ShapView, PetCategoryView
  10. # 根据view的类型,判断所需的权限名字
  11. if isinstance(view, CageView) or isinstance(view, FosterView):
  12. authority_name = "foster"
  13. elif isinstance(view, PrecontractView):
  14. authority_name = "precontract"
  15. elif isinstance(view, PetView):
  16. authority_name = "memeber"
  17. else:
  18. authority_name = "precontract"
  19. try:
  20. user = request.user # 自己定义的user model
  21. role = user.role
  22. authority = Authority.objects.get(role=role, state='1')
  23. authority_info = authority.get_info()
  24. if authority_info[authority_name] != '1':
  25. # 判断是否具有权限,返回False,则最终返回403状态,
  26. # 而这里需要我们自定义处理的结果,所以raise一个自己写的异常
  27. # return False
  28. raise RightDenied
  29. # 权限通过,返回True
  30. return True
  31. except BaseException:
  32. raise RightDenied
  33. # return False
  34. raise PermissionDenied

异常处理

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

  1. import traceback
  2. from rest_framework.views import exception_handler
  3. from rest_framework.response import Response
  4. from django.http import HttpResponseRedirect
  5. import logging
  6. logger = logging.getLogger('views')
  7. def custom_exception_handler(exc, context):
  8. # Call REST framework's default exception handler first,
  9. # to get the standard error response.
  10. response = exception_handler(exc, context)
  11. # response = None
  12. # Now add the HTTP status code to the response.
  13. # 捕获程序中的断言异常,作相关的处理,
  14. if response is not None:
  15. # raise exc
  16. response.data['status_code'] = response.status_code
  17. response.data['error'] = str(exc)
  18. elif isinstance(exc, AssertionError):
  19. # 断言错误,
  20. response.data[‘detail’] = "断言错误"
  21. response.data['error'] = str(exc)
  22. else:
  23. raise exc
  24. return response

分页

示例如下

  1. class CustomPagination(pagination.PageNumberPagination):
  2. page_size = 20 # 默认分页大小
  3. page_size_query_param = 'page_size' # 分页大小控制
  4. max_page_size = 30
  5. def get_paginated_response(self, data):
  6. # 自定义分页后的数据返回格式
  7. return Response({
  8. 'links': {
  9. 'next': self.get_next_link(),
  10. 'previous': self.get_previous_link()
  11. },
  12. 'count': self.page.paginator.count,
  13. 'results': data
  14. })

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)转换流其实是一个字符流 字符流 = 字节流 + 编码表 (3)编码表 ...

  2. C#中三个关键字params,Ref,out

    关于这三个关键字之前可以研究一下原本的一些操作 using System; using System.Collections.Generic; using System.Text; namespace ...

  3. linq(查询)

    1.改变数据库某一字段的属性 db.tableName.ToList().ForEach(x => x.State = false); 2.排序 db.tableName..toList().O ...

  4. Scala 知识点掌握1

    Scala知识点巩固 1.Scala简介 Scala是一门面向对象和面向函数的编程语言,是一门静态编程语言,如 Java Scala(变量类型在编译阶段确定):源码文件需要基于 JVM 运行的. 动态 ...

  5. HDU 5012 骰子旋转(DFS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5012 保存骰子的状态,然后用dfs或者bfs搜索 还是再讲一下dfs 我们的目标是找一个与b相同,且转次数最少的 ...

  6. XHR的应用场景

    一.简史 IE5.5最早实现XHR,需要通过ActiveXObject创建xhr实例,直到IE7才定义了XMLHttpRequest对象.IE5.5实现XHR之后,其他浏览器紧随其后实现了XHR,直接 ...

  7. html和css命名-望文生义

    HTML+CSS命名规则 在一个内容较多的HTML页面中,需要设计许多不同的框架,再为这些不同的框架及内容进行分类,给予相应的名称,从而使得网页结构更加清晰,也为工作提供了方便.许多新手朋友在设计一个 ...

  8. 有关background 背景图片不能显示

    首先有两个概念 绝对路径,从根目录为起点到你所在的目录: 相对路径,从一个目录为起点到你所在的目录. 例如:              ┍ A文件夹           C -|            ...

  9. PLSQL Developer中几个功能

    1,登录后默认自动选中My Objects 默认情况下,PLSQL Developer登录后,Brower里会选择All objects,如果你登录的用户是dba,要展开tables目录,正常情况都需 ...

  10. SharePoint 2013 - Callout

    1. 没有OOTB的方法对Callout进行修改,Callout可以使用在以下范围: Document Library Assert Library Images Library Pages Libr ...