drf-7

认证组件

# 以后,有的接口需要登录后才能访问,有的接口,不登录就能访问
  -登录认证的限制
  
# 写一个登录接口,返回token,以后只要带着token过来,就是登录了,不带,就没有登录


# 查询所有不需要登录就能访问
# 查询单个,需要登录才能访问

认证组件使用步骤

# 1 写一个认证类,继承BaseAuthentication
# 2 重写authenticate方法,在该方法在中实现登录认证:token在哪带的?如果认证它是登录了
# 3 如果认证成功,放回两个值【返回None或两个值】
# 4 认证不通过,抛异常AuthenticationFailed
# 5 局部使用和全局使用
-局部:只在某个视图类使用【当前视图类管理的所有接口】
			class BookDetailView(ViewSetMixin,RetrieveAPIView):
  				authentication_classes = [LoginAuth]
 -全局:全局所有接口都生效(登录接口不要)
REST_FRAMEWORK = {
 'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth']
}

-局部禁用:
	class BookDetailView(ViewSetMixin, RetrieveAPIView):
            authentication_classes = [] 

新建authenticate.py文件

img

全局方式导入:

img

可以在drf的settings.py中看到

img

代码

###视图
# 查询所有
class BookView(ViewSetMixin, ListAPIView):
  queryset = Book.objects.all()
  serializer_class = BookSerializer
  
 
# 查询单个
class BookDetailView(ViewSetMixin,RetrieveAPIView):
		queryset = Book.objects.all()
    serializer_class = BookSerializer
    #  authentication_classes = [LoginAuth]  # 需要写一个认证类,需要咱们写
    
 # 认证类代码
class LoginAuth(BaseAuthentication):
  def authenticate(self, request):
    # 在这里实现认证,如果是登录的,继续往后走返回两个值,如果不是抛异常
    # 请求中是否携带token,判断是否登录,放在地址栏中
     token = request.query_params.get('token', None)
        if token:  # 前端传入token了,去表中查,如果能查到,登录了,返回两个值[固定的:当前登录用户,token]
            user_token = UserToken.objects.filter(token=token).first()
            if user_token:
                return user_token.user, token
            else:
                # 没有登录抛异常
                raise AuthenticationFailed('token认证失败')
        else:
            raise AuthenticationFailed('token没传')

  
##### 路由代码
router.register('books', views.BookView, 'books')
router.register('books', views.BookDetailView, 'books')

注意:

不要在配置文件中乱导入不使用的东西,否者会报错。

因为,Django的运行是先从配置文件加载的,而导入其他的,文件都没有加载到就直接导入了就会报错。

权限组件

# 即使登录成功了, 有些接口,还是不能访问,因为没有权限

# 登录后,有的接口有权限访问,有的没有权限访问

# 查询单个和查询所有,都要登录才能访问--->全局认证
-查询单个需要超级管理员才能访问
-查询所有,所有登录用户都能访问

# 权限是一个字段,在User表中, 加入user_type字段

权限的使用

# 1 写一个权限类,继承BasePermission
# 2 重写has_permission方法,在该方法在中实现权限认证,在这方法中,request.user就是当前登录用户
# 3 如果有权限,返回Ture
# 4 没有权限,返回False,定制返回的中文:self.message='中文'
# 5 局部使用和全局使用
-局部:只在某个视图类中使用【当前视图类管理的所有接口】
  class BookDetailView(ViewSetMixin,RetrieveAPIView):
  		permission_classes = [CommonPermission]
 -全局:全局所有接口都生效
  		 REST_FRAMEWORK = {
            'DEFAULT_PERMISSION_CLASSES': [
                'app01.permissions.CommonPermission',
            ],

        }
    
    -局部禁用:
    	 class BookDetailView(ViewSetMixin, RetrieveAPIView):
            permission_classes = [] 

当登入的用户的user_type(权限)为1时就是超级管理员就能够访问单条数据

img

频率组件

# 控制某个接口访问频率(次数)
# 查询所有接口,同一个ip一分钟只能访问5个

使用步骤

# 1 写一个频率类 继承SimpleRateThrottle
# 2 重写get_cache_key方法,放回什么,就以什么做限制---->ip,用户id做限制
# 3 配置一个类属性:scope = 'book_5_m'
# 4 在配置文件中配置
  'DEFAULT_THROTTLE_RATES': {
        'book_5_m': '5/m',
    },
# 5 局部使用和全局使用
	-局部:只在某个视图类中使用【当前视图类管理的所有接口】
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
    		throttle_classes = [CommonThrottle]
    -全局:全局所有接口都生效
          REST_FRAMEWORK = {
             'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],

        }
    
    -局部禁用:
    	 class BookDetailView(ViewSetMixin, RetrieveAPIView):
            throttle_classes = [] 

分用户ID和IP做限制

img

request.META

img

# request.META
	一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器。
	REMOTE_ADDR —— 客户端的IP 地址
  REMOTE_HOST —— 客户端的主机名
  REMOTE_USER —— 服务器认证后的用户
  更多:https://www.liuqingzheng.top/python/Django%E6%A1%86%E6%9E%B6/6-%E8%A7%86%E5%9B%BE%E5%B1%82/

别忘记配类属性:scope = 'book_5_m'

img

在settings.py源码中

img

得在自己的settings文件中配置,一分钟只能访问5次。有h 1小时多少次

img

过滤排序

5个接口中,只有一个接口需要有过滤和排序,查询所有接口

继承APIView写 (伪代码)

class BookView(APIView):
  def get(self, request):
    search = request.query_params.get('search')
    books = Book.objects.filter(name=self.name)

内置过滤类的使用【继承GenericAPIView】

class BookView(ViewSetMixin,ListAPIView):
  queryset = Book.objects.all()
  serializer_class = BookSerializer
  # SearchFilter内置的,固定用法,模糊匹配
  # 就有过滤功能了,指定按哪个字段过滤
  filter_backends =【SearchFilter】
   # search_fields = ['name']  # 可以按名字模糊匹配
    search_fields = ['name','price']  # 可以按名字模糊匹配或价格模糊匹配
    
 # 可以使用的搜索方式
	http://127.0.0.1:8000/api/v1/books/?search=红  # name或price中只要有红就会搜出来
            
            
# 继承APIView如何写,完全自己写,麻烦,但是清晰     

img

在地址栏中必须以search搜索的模糊查询,查找search_fields中写的字段中包含有搜索的就会查找出来,search_fields中可以写多个字段,

img

使用第三方django-filter实现过滤

安装:Django-filter
from django_fliter.rest_framework import djangoFilterBackend
class BookView(ViewSetMixin, ListAPIView):
  queryset = Book.objects.all()
  serializer_class = BookSerializer
  permission_classes = []
  authentication_classes = []
  throttle_classes = []
  filter_backends = ['name', 'price']  # 支持完整匹配 name=西游记&price=110
  
# 支持的查询方式
http://127.0.0.1:8000/api/v1/books/?price=939
http://127.0.0.1:8000/api/v1/books/?price=939&name=红楼梦

注意跟内置的不一样了:

img

以你在filterset_filelds中写的字段搜索的完整匹配

img

自己定制过滤类实现过滤

# 查询图书价格大于100的所有图书
http://127.0.0.1:8000/api/v1/books/?price_gt=100
    
# 第一步:定义一个过滤类。继承BaseFilterBackend,重写filter——queryset方法

class CommonFilter(BaseFilterBackend):
  def filter_queryset(self, request,view):
    # 在里面是实现过滤,返回qs对象,就是过滤后的数据
    price_gt = requset.query_params.get('price_gt',None)
    if price_gt:
      qs = quesryset.filter(price__get=int(price_get))
      return qs
    else:
      return queryset
# 第二步:配置在视图类上
class BookView(ViewSetMixin, ListAPIView):
  quesryset = Book.objects.all()
  serilizer_class = Bookserializer
  
  filter_backends = [CommonFilter]  # 可以定制多个,从左往右,依次执行

注意这里要CharField是不支持__gt大于的查询比较

img

可以自己指定字段过滤,通过在定义的过滤类里反射

img

img

排序的使用

# 内置的就够了
class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [OrderingFilter]  
    ordering_fields = ['price']
    
 # 支持的查询方法:
    http://127.0.0.1:8000/api/v1/books/?ordering=price
    http://127.0.0.1:8000/api/v1/books/?ordering=-price
   http://127.0.0.1:8000/api/v1/books/?ordering=-id,price

img

分页

分页,只有查询所有接口,才有分页

# derf内置分了三个分页器对应三种分页方式

# 内置的分页类不能直接使用,需要继承,定制一些参数后才能使用

源码中GenericAPIView ---> generic中

img

img

为啥不在是一个列表了呢,因为你分页不可能会出现多个分页方式了。

img

分页的使用,自定义一个分页列(三种)

方式一:网页端分页

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination

class CommonpageNumberPagination(PageNumberPagination):
  page_size = 2  # 每页显示2条
  page_query_param = 'page'  # page=10 查询第10页的数据,每页显示2条
  page_size_query_param = 'size'  # page=10&size=5  查询第10页,每页显示5条(这里只要你不写size每页展示2条,写了定义的size就按你写的)
  max_page_size = 5  # 每页显示最大10条

img

方式二:偏移分页

# LimitOffset
class CommonLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 3  # 每页显示2条
    limit_query_param = 'limit'  # limit=3   取3条
    offset_query_param = 'offset'  # offset=1  从第一个位置开始,取limit条
    max_limit = 5
    # offset=3&limit=2      0  1 2 3 4 5

img

方式三:游标分页

# app 用下面
游标分页,只能下一页,上一页
class CommonCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'  # 查询参数
    page_size = 2  # 每页多少条
    ordering = 'id'  # 排序字段

img

以上方式一种配置在视图类上

# 配置在视图类上即可
class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    permission_classes = []
    authentication_classes = []
    throttle_classes = []
    # 之前的东西一样用 ,内置的分页类不能直接使用,需要继承去定制一些参数后才能使用
    # pagination_class = PageNumberPagination
    #基本分页方式(基本是这种,网页端):http://127.0.0.1:8000/api/v1/books/?page=2&size=3

    # pagination_class = LimitOffsetPagination
    # 偏移分页 http://127.0.0.1:8000/api/v1/books/?limit=4&offset=1
    # 从第一条开始,取4条

    pagination_class = CommonCursorPagination
    # 游标分页,只能下一页,上一页,不能跳到中间,但它的效率最高,大数据量分页,使用这种较好
posted @   hugmi男孩  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
  1. 1 原来你也在这里 周笔畅
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
起风了 - 吴青峰
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 米果

作曲 : 高橋優

编曲 : 刘胡轶/貢多杰

制作人 : 刘胡轶/吴青峰

配唱制作人 : 刘胡轶

乐器监制 : 刘胡轶

吉他 : 胡晨

贝斯 : 甯子达

弦乐录音棚 : 中国剧院录音棚

录音工程师 : 倪涵文/李游/李杨/邢铜/韩宽/李巍

录音监制 : 倪涵文/李游

混音&母带工作室 : OKmastering studio

混音&母带工程师 : 全相彦

制作协力 : 刘西洋

制作发行 : 智慧大狗 × 天才联盟

出品人 : 张葛

监制 : 崔恕/王明宇

弦乐监制 : 李朋

弦乐 : 国际首席爱乐乐团

鼓(打击乐):祁大为

和音编写&演唱:鱼椒盐

人声&吉他&鼓(打击乐)录音棚:55Tec studio

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

这一路上走走停停

这一路上走走停停

顺着少年漂流的痕迹

迈出车站的前一刻

竟有些犹豫

不禁笑这近乡情怯

不禁笑这近乡情怯

仍无可避免

而长野的天

依旧那么暖

风吹起了从前

从前初识这世间

从前初识这世间

万般流连

看着天边似在眼前

也甘愿赴汤蹈火去走它一遍

如今走过这世间

如今走过这世间

万般流连

翻过岁月不同侧脸

措不及防闯入你的笑颜

我曾难自拔于世界之大

我曾难自拔于世界之大

也沉溺于其中梦话

不得真假 不做挣扎 不惧笑话

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

逆着光行走 任风吹雨打

短短的路走走停停

短短的路走走停停

也有了几分的距离

不知抚摸的是故事 还是段心情

也许期待的不过是 与时间为敌

再次看到你

微凉晨光里

笑得很甜蜜

从前初识这世间

从前初识这世间

万般流连

看着天边似在眼前

也甘愿赴汤蹈火去走它一遍

如今走过这世间

如今走过这世间

万般流连

翻过岁月不同侧脸

措不及防闯入你的笑颜

我曾难自拔于世界之大

我曾难自拔于世界之大

也沉溺于其中梦话

不得真假 不做挣扎 不惧笑话

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

晚风吹起你鬓间的白发

晚风吹起你鬓间的白发

抚平回忆留下的疤

你的眼中 明暗交杂 一笑生花

我仍感叹于世界之大

我仍感叹于世界之大

也沉醉于儿时情话

不剩真假 不做挣扎 无谓笑话

我终将青春还给了她

连同指尖弹出的盛夏

心之所动 就随风去了

以爱之名 你还愿意吗

点击右上角即可分享
微信分享提示