首页 > 其他分享 >drf之认证、权限、频率控制、排序、过滤、分页

drf之认证、权限、频率控制、排序、过滤、分页

时间:2024-04-17 20:46:11浏览次数:22  
标签:排序 name models price request user 权限 class drf

【认证】

  models.py
 1 from django.db import models
 2 
 3 
 4 # Create your models here.
 5 class User(models.Model):
 6     username = models.CharField(max_length=50)
 7     password = models.CharField(max_length=50)
 8     user_type = models.IntegerField(choices=((1, '普通用户'), (2, '普通管理员'), (3, '超级管理员')), default=1)
 9   # 认证登录的用户是否是user里的用户
10     @property
11     def is_authenticated(self):
12         return True
13 
14 
15 class UserToken(models.Model):
16     user = models.OneToOneField(User, on_delete=models.CASCADE)
17     token = models.CharField(max_length=500)
18 
19 
20 class Book(models.Model):
21     name = models.CharField(max_length=50)
22     publish = models.CharField(max_length=50)
23     price = models.IntegerField()
24 
25     def __str__(self):
26         return self.name

 

VIEWS.PY

# ============================================认证类
# 登录接口
class UserView(ViewSet):
    authentication_classes = []
    # 登录接口局部禁用
    permission_classes = []

    @action(methods=['POST'], detail=False)
    def login(self, request):
        # 用户名,密码在request.data中
        username = request.data.get('username')
        password = request.data.get('password')
        # 验证用户名和密码
        user = User.objects.filter(username=username, password=password).first()
        if user:
            # 验证通过,生成随机字符串,存到usertoken中
            # 之前存在就修改,没有就新增
            token = str(uuid.uuid4())
            UserToken.objects.update_or_create(user=user, defaults={'token': token})
            return Response({'code': 200, 'msg': '登录成功', 'token': token})
        else:
            return Response({'code': 400, 'msg': '用户名或密码错误'})

=======================================================
authenticate.py 里面代码
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

from app05.models import UserToken


class LoginAuth(BaseAuthentication):
  重写父类里面的authenticate方法
def authenticate(self, request):
# request是新的,从request中取出用户携带的token
    # 放在请求头中
        token = request.META.get('HTTP_TOKEN')
user_token = UserToken.objects.filter(token=token).first()
if user_token:
user = user_token.user
return user, token
else:
raise AuthenticationFailed('认证失败')

-----------------------------------
-----------------------------------
总结:
# 1 写一个认证类,继承BaseAuthentication
# 2 重写authenticate方法,在该方法在中实现登录认证:token在哪带的?
# 3 如果认证成功,返回两个值【返回None或两个值】
# 4 认证不通过,抛异常AuthenticationFailed
# 5 局部使用和全局使用

-局部:只在某个视图类中使用( 当前视图类管理的所有接口都会在运行前进行认证的校验 )
class BookDetailView(ViewSetMixin, RetrieveAPIView):
    authentication_classes = [LoginAuth]
-----------------------------------

-全局:全局所有接口都生效(但是登录接口不能要,其他接口需要登录后才能访问,登录接口不可能还需要登录后才能访问,那就没法登录了!!!)
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES':['app05.authenticate.LoginAuth']}
 
-----------------------------------

-所以要局部禁用 把authentication_classes设为空列表 取消掉全局的登录认证:
class UserView(ViewSet):
    authentication_classes = []

    @action(methods=['POST'], detail=False)
    def login(self, request):
        pass
 

 

.。




(权限)
views.py
# 权限,需要普通用户以上才能访问,但是必须要认证通过
class BooksView(GenericViewSet, ListModelMixin, DestroyModelMixin, CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # authentication_classes = [LoginAuth]
  # 局部限制
  permission_classes = []

===========================================
permissions.py文件
from rest_framework.permissions import BasePermission

# 权限,只有超级用户才能访问,其他用户没有权限
class UserPermission(BasePermission):
def has_permission(self, request, view):
# 判断权限,如果有权限,返回True,否则返回False
# 认证通过,拿到当前登录用户,request.user中拿到
# is_authenticated在用户表中没有,需要去重新定义
if request.user.is_authenticated:
if request.user.user_type == 3:
return True
else:
# 定制提示信息,get_user_type_display拿到数字对应的字符串
user_type = request.user.get_user_type_display()
self.message = f'你是{user_type}没有权限访问'
return False
else:
self.message = '请先登录'
return False
----------------------------------
总结

# 1 写一个权限类,继承BasePermission
# 2 重写has_permission方法,在该方法在中实现权限认证,在这方法中,request.user就是当前登录用户
# 3 如果有权限,返回True
# 4 没有权限,返回False,定制返回的中文: self.message='中文'


# 5 局部使用和全局使用

-局部:只在某个视图类中使用【当前视图类管理的所有接口】
class BookDetailView(ViewSetMixin, RetrieveAPIView):
	permission_classes = [CommonPermission]

-------------------------------------
-全局:全局所有接口都生效
    REST_FRAMEWORK = {'DEFAULT_PERMISSION_CLASSES': [
                'app01.permissions.CommonPermission'],
                     }

-如果要全局生效,必须配合局部禁用,在不需要权限认证的视图类里面,把permission_classes设为空列表

 

(频率限制)

views.py


# 需求:查询所有接口,同一个ip一分钟只能访问3次

# 频率类,不继承BaseThrottle,继承SimpleRateThrottle,目的少写代码
# 重写SimpleRateThrottle里面的 get_cache_key 方法

class PublishView(GenericViewSet): # 方式一:做限制,局部限制使用 # permission_classes = [UserPermission] # 频率限制使用 throttle_classes = [CustomThrottle] def list(self, request): return Response('所有数据')

================================
throttling.py文件
# 频率得使用

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle

class CustomThrottle(SimpleRateThrottle):
# 1分钟3次
rate = '3/m'
def get_cache_key(self, request, view):
# 返回什么,就会以什么做限制---ip地址限制:用户id
return request.META.get('REMOTE_ADDR')
--------------------------------------

总结
# 1 写一个频率类,继承SimpleRateThrottle
# 2 重写get_cache_key方法,返回什么,就以什么做限制----》ip,用户id做限制
# 3 配置一个类属性:scope = 'book_5_m'
# 4 在配置文件中配置
  'DEFAULT_THROTTLE_RATES': {
        'book_5_m': '5/m',
    },

# 5 局部使用和全局使用
-局部:只在某个视图类中使用【当前视图类管理的所有接口】
class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    throttle_classes = [CommonThrottle]  # 局部配置


-全局:全局所有接口都生效
REST_FRAMEWORK = {'DEFAULT_THROTTLE_RATES': {'rate888': '5/m',},

    'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],
                     }

-要配合局部禁用,将不需要频率限制的接口的视图类里面,把throttle_classes设为空列表 :


 

(分页。排序。过滤)

 1 # 查询所有图书接口
 2 class BookListView(GenericViewSet, ListModelMixin):
 3     queryset = Book.objects.all()
 4     serializer_class = BookSerializer
 5     permission_classes = []
 6     throttle_classes = []
 7     # 分页
 8     # pagination_class = CommonPageNumberPagination
 9     # pagination_class = CommonLimitOffsetPagination
10     pagination_class = CommonCursorPagination
11 
12     # 排序,必须继承GenericAPIView,在视图类中配置
13     # filter_backends = [OrderingFilter]
14     # 按照哪个字段排序,默认按照id排序,按照字段排序以后是按照价格升序,如果想降序:ordering=-price
15     # ordering_fields = ['price']
16 
17     # 过滤,可以和排序一起用
18     # filter_backends = [OrderingFilter, SearchFilter]
19     # ordering_fields = ['price', 'name']
20     # # 也可以多个字段模糊匹配
21     # search_fields = ['name', 'publish']
22 
23     # 第三方过滤==============按照名字精准匹配  pip3 install django-filter
24     # filter_backends = [OrderingFilter, DjangoFilterBackend]
25     # filterset_fields = ['name', 'price']
26 
27     # 自定义过滤
28     filter_backends = [CommonFilter]
29 
30     # 排序之定制返回格式
31     # def list(self, request, *args, **kwargs):
32     #     qs = self.get_queryset()
33     #     ser = BookSerializer(instance=qs, many=True)
34     #     return Response({'code': 200, 'msg': '请求成功', 'results': ser.data})

================================================================================================分页
page.py
from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination, CursorPagination


# 基本分页
class CommonPageNumberPagination(PageNumberPagination):
page_size = 2 # 每页显示2条
page_query_param = 'page' # http://127.0.0.1:8008/app01/api/v1/books1/?page=2
page_size_query_param = 'size' # http://127.0.0.1:8008/app01/api/v1/books1/?page=2&size=3 查询第二页,每页显示3条
max_page_size = 10 # 每页最多显示10条


# 偏移分页
class CommonLimitOffsetPagination(LimitOffsetPagination):
default_limit = 2 # 每页显示2条
limit_query_param = 'limit' # 控制每页显示多少条
# http://127.0.0.1:8013/app05/api/v1/books1/?offset=3 从第3条开始,取两条
# http://127.0.0.1:8013/app05/api/v1/books1/?offset=3&limit=1 从第3条开始,取1条
offset_query_param = 'offset' # 偏移量
max_limit = 10


# 游标分页
class CommonCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 查询条件 http://127.0.0.1:8008/app01/api/v1/books1/?cursor=asfasf
page_size = 2
ordering = 'id' # 排序字段,只能上一页,下一页这样选择,聊率高

==========================================================================================过滤
# 自定义过滤类
from django.db.models import Q
from rest_framework.filters import BaseFilterBackend


class CommonFilter(BaseFilterBackend):
# 必须重写这个方法
def filter_queryset(self, request, queryset, view):
# 完成过滤,返回 qs对象
# 查询价格为66 或者 名字中包含海的数据
# http://127.0.0.1:8008/app01/api/v1/books1/?price=42&name=红
price = request.query_params.get('price', None)
name = request.query_params.get('name', None)
if price and name:
queryset = queryset.filter(Q(price=price) | Q(name__contains=name))
if price:
# queryset=queryset.filter(Q(price=price) | Q(name__contains=name))
queryset = queryset.filter(price=price)
if name:
queryset = queryset.filter(name__contains=name)

return queryset
PS:补充
  
# 安装:django-filter
pip3.8 install django-filter==22.1 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/
腾讯源太垃圾了,用豆瓣

 

 

 

路由

 全局生效的settings里面的配置

 



标签:排序,name,models,price,request,user,权限,class,drf
From: https://www.cnblogs.com/liuliu1/p/18141738

相关文章

  • 新连点器和bat不弹黑窗口且自动获取管理员权限
    标题好长新的连点器相比原来那个c语言版,这次使用python编写,添加了简单的图形界面,参数调整非常简单(指的是直接编辑源码)直接贴完整代码:#导入模块importtkinterastkimportthreadingimportpyautoguiimportkeyboard#定义全局变量running=False#是否开启连点int......
  • js带注释的冒泡排序算法
    一、简述冒泡排序(BubbleSort)是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果二者的顺序(如从大到小、首字母从A到Z)错误就交换。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法......
  • day12_我的Java学习笔记 (package包、权限修饰符_private+缺省+protected+public、fin
    1.包IDEA配置自动导包:2.权限修饰符同一个类中的,【private、缺省、protected、public】都可以访问同一个包中的其他类,【private】不可以访问,【缺省、protected、public】都可以访问不同包下的无关类,【private、缺省、protected】都不可以访问,只有【public......
  • vbs提示没有在该机执行windows脚本宿主的权限。请与系统管理员联系
    <p>最近在项目中使用VBS来实现图片的批量删除和批量导入功能,但不知道为什么,只要在我机器上一运行VBS文件就提示“没有在该机执行windows脚本宿主的权限。请与系统管理员联系。”的错误。下面贴出本人的解决方法,并附上图片批量导入及批量删除的VBS代码。</......
  • 账号和权限管理
    账号和权限管理目录账号和权限管理一、用户账号和组账号的概述1、用户账号的分类2、组账号的分类3、标识号分类二、用户账号文件1、/etc/passwd1.1作用1.2字段分析2、/etc/shaow2.1作用2.2字段分析三、用户账号管理1、添加用户账号-useradd1.1作用1.2命令格式1.3常用选......
  • 80、SpringBoot3 SpringSecurity Mybatisplus最新版 整合 实现登入权限控制
    1、导入pom依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apac......
  • list集合的排序
    list集合的排序使用常用的sort方法排序和stream流的方式排序packagecom.liucy.meiriyilian.sort;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;importjava.util.List;importjava.util.stream.Collectors;/***@Authorli......
  • 常见的排序算法——希尔排序
    本文记述了希尔排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。◆思想给定元素之间的间隔h,将所有间隔为h的元素作为独立的待排序范围,可以得到h个这样的子范围。针对每个子范围执行插入排序,使得任意间隔为h的元素是有序的。然后缩小间距......
  • 3小时搞定DRF框架 | Django REST framework前后端分离框架实践
    DRF(全称DjangoRESTframework)是一个用于构建WebAPI的强力工具集,是一个基于Django的PythonWeb框架,它为开发人员提供了一套快速开发RESTfulAPI的工具,它能够自动化API可视化、文档化,实现接口的自动化测试以及自动化的API路由、序列化、视图、验证、分页、版本管理、认证等......
  • 如何在PDF文件中删除限制,pdf删除打印权限,PDF删除编辑权限去除
    您是否有一个可以打开但无法编辑、打印或复制所选文本到剪贴板的AdobePDF文件?有一个简单的解决方案:只需单击几下,文件就可以不受保护。坏消息:您将需要软件。好消息:我们已经为您打造了一个。AdobePDF格式定义了几种保护方法。可以保护PDF文件不被打开(因此只需打开和查看文......