当前位置:   article > 正文

drf框架----权限_drf 用户模型

drf 用户模型

限流

DRF 限流原理:
匿名用户,使用ip地址标识访问者,存储每次访问的时间节点。

缓存: throttle_anon_ip<==> [时间戳1,时间戳2,…]
判断历史访问时间节点的长度 >= 限流次数,则拒绝;

每次请求过来时,查看self.history中是否有访问历史,若没有,则允许访问,并存储当前访问的时间节点self.history.inser(0, self.now);若有访问历史,先查看是否有过期的记录self.history[-1] <= self.now-self.duration,有则删除,然后判断访问次数是否超限len(self.history)。(及时循环删除过期的访问节点)

# 全局配置
# 全局配置
    REST_FRAMEWORK = {
      'DEFAULT_THROTTLE_CLASSES': (
          # 限制所有匿名未认证用户,使用IP区分用户
          'rest_framework.throttling.AnonRateThrottle',
          # 限制认证用户
          'rest_framework.throttling.UserRateThrottle'
      ),
      # 配置限流频率
      'DEFAULT_THROTTLE_RATES': {
          # 可以使用 second, minute, hour 或day来指明周期
          # 匿名用户,每分钟3次请求
          'anon': '3/minute',
          # 认证用户,每分钟5次请求
          'user': '5/minute'
      }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

分页

  1. 分页的简单使用
from rest_framework.pagination import PageNumberPagination

class MyPagination(PageNumberPagination):
	page_size = 5  # 默认每页的条数
	max_page_size = 6 # 最多每页条数
	page_query_param = "page" # 页码的查询参数  
	page_size_query_param = "pagesize" #  查询参数中的每页显示的条数, 以此为准

# 用户信息视图
class UserInfoViewSet(ModelViewSet):
	queryset = User.objects.all()
	serializer_class = UserSer
	pagination_class = MyPagination
	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里插入图片描述
2. 分页的重写

from django.core.paginator import InvalidPage
# 重写 分页方法
class MyPagination(PageNumberPagination):
    """全局的分页,所有的list请求都会调用"""
	# 默认每页显示的条数,前端不传参数时,默认
    page_size = 10  
    max_page_size = 20  # 每页最大显示的条数
    #页码  参数  如 /users/?page=2&pagesize=3
    page_query_param = "page"
    page_size_query_param = 'pagesize'  # 前端发送的页数关键字名
   
	# 可以重写分页的方法
    def paginate_queryset(self, queryset, request, view=None):
        """
        Paginate a queryset if required, either returning a
        page object, or `None` if pagination is not configured for this view.
        """
        empty = True
		
		# 请求的分页 每页条数
        page_size = self.get_page_size(request)
        if not page_size:
        	# 没有要求分页,返回None
            return None

        paginator = self.django_paginator_class(queryset, page_size)
        # 获取页码
        page_number = request.query_params.get(self.page_query_param, 1)
        # 最后一页
        if page_number in self.last_page_strings:
            page_number = paginator.num_pages

        try:
            self.page = paginator.page(page_number)
        except InvalidPage as exc:

            empty = False
            

        if paginator.num_pages > 1 and self.template is not None:
            # The browsable API should display pagination controls.
            self.display_page_controls = True

        self.request = request

        if not empty: # 出异常
            self.page = []

        return list(self.page)

    def get_paginated_response(self, data): # 传入当前分页的数据
        return Response(OrderedDict([
            ('count', self.page.paginator.count if self.page else 0),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('code', 0),
            ('message', 'Ok'),
            ('results', data),
        ]))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

模型类

from django.contrib.auth.models import AbstractUser
from django.db import models
 
# 用户模型类
class User(AbstractUser):
	mobile = models.CharField("手机号", max_length=11)
	user_type = models.ForeignKey(UserRole, on_delete=models.CASCADE, verbose_name="用户角色")

# 角色模型类
class UserRole(models.Model):
	ROLES = (
		(1, "普通会员"),
		(2, "黄金会员"),
		(3, "白金会员"),
		(4, "钻石会员")
	)
	role = models.IntegerField("角色", choices=ROLES)

# API 地址表
class Urls(models.Model):
	url = models.CharField("路由地址", max_length=200)
	visit_role = models.ManyToMany(Role)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述

DRF的权限

局部鉴权

from rest_framework.permissions import BasePermission
from rest_framework.permissions import IsAuthenticated # 是否登录
from rest_framework.throttling import BaseThrottle # 访问频率

class MyPermission(BasePermission)
	def has_permission(self, request, view):
		# 权限校验通过
		return True
		#否则 return False


# 局部认证、鉴权、限流
class CheckView(APIView):
	pagination_class = MyPagination
	authentication_classes = [MyAuthentication,]
	permission_classes = (IsAuthenticated, MyPermission)
	throttle_classes = []	
	queryset = User.objects.all()
	serializer_class = UserSer
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

全局鉴权

from rest_framework.permissions import BasePermission
import re

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        # view为对应的要进入的视图
        print("我的认证权限类:", view)
        # 权限认证,忽略登录的视图
        if re.findall(r"login|admin", request.path_info, re.I):
            return True

        # 会话保持认证通过,会有request.user
        # 这里先查询用户
        user = User.objects.filter(id=1).first()
        for i in user.role.all():

            if i.name == "管理员":
                # 有权限访问
                return True
        else: # 循环正常结束时,执行
            return False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

全局配置rest_framework的鉴权


REST_FRAMEWORK = {
	"DEFAULT_PERMISSION_CLASSES": ('users.utils.MyPermission'),
}
  • 1
  • 2
  • 3
  • 4
'
运行
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/944404
推荐阅读
相关标签
  

闽ICP备14008679号