4 权限组件、频率、3组件总结
https://www.cnblogs.com/yuanchenqi/articles/8719520.html
https://www.cnblogs.com/alice-bj/p/9252207.html#_label3
1、权限组件
1. 源码
1.权限函数
2.API settings配置
3.核心代码
View下的 self,代表view
‘message’ 为认证错误返回的信息
3. 需求:不是vip,不能看author
user表
数据库迁移与生成
我要知道这次的请求人是谁
在auth认证组件中中里面有 user
权限用到认证中的信息
utils
view
utils里的 类 和 view里的实例对象,必须一致
test
通过了第一层的认证,没有通过第二次的权限
切换超级用户登录
4. 全局配置
通过权限认证 true
没有通过 false
test
任何页面都需要权限才能访问
5. Code与Question
Question1
books 先auth一下,才有request.name
不然都是,
Question 2
auth的全局配置会影响login页面
code
models
from django.db import models # Create your models here. class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) type_choices = ((1,"普通用户"),(2,'SVip'),(3,'SSVip')) user_type = models.IntegerField(choices=type_choices,default=1)
views
# Author from .models import Author from app01.serilizer import AuthorModelSerializers from rest_framework import viewsets from app01.utils import SVipPermission class AuthorView(viewsets.ModelViewSet): # authentication_classes = [TokenAuth] # 加上这个,走自己的认证,也就是不认证 # 不加的话,自己没有,走全局的认证 permission_classes = [SVipPermission,] # list数据 # create数据 # 继承APIView queryset = Author.objects.all() # queryset,serilizers 名称不能修改 serializer_class = AuthorModelSerializers
utils
from .models import User class SVipPermission(object): message = "只有超级用户才能访问" def has_permission(self,request,view): username = request.user print(username) user_type = User.objects.filter(name=username).first().user_type # 对象直接 . 自己的属性 if user_type == 3: return True # 通过权限认证,可以看author表 else: return False
settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],
# 'DEFAULT_PERMISSION_CLASSES':['app01.utils.SVipPermission']
}
2. 频率组件
1、核心代码
2. 要求访问站点的频率不能超过每分钟20次
ip time
3.request里面有什么内容
请求头
客户端的ip
通过什么都不做
不拖过才返回错误信息
请求头必会的
refer
useraget
contentype
4. 全局配置
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'], 'DEFAULT_PERMISSION_CLASSES':['app01.utils.SVipPermission'], 'DEFAULT_THROTTLE_CLASSES':['app01.utils.VisitRateThrottle'], 'DEFAULT_THROTTLE_RATES':{ 'visit_rate':'1/m' } }
5.局部配置
utils
from rest_framework.throttling import BaseThrottle VISIT_RECORD={} class VisitThrottle(BaseThrottle): def __init__(self): self.history=None def allow_request(self,request,view): remote_addr = request.META.get('REMOTE_ADDR') print(remote_addr) import time ctime=time.time() if remote_addr not in VISIT_RECORD: VISIT_RECORD[remote_addr]=[ctime,] return True history=VISIT_RECORD.get(remote_addr) self.history=history while history and history[-1]<ctime-60: history.pop() if len(history)<3: history.insert(0,ctime) return True else: return False def wait(self): import time ctime=time.time() return 60-(ctime-self.history[-1])
view
from app01.service.throttles import * class BookViewSet(generics.ListCreateAPIView): throttle_classes = [VisitThrottle,] queryset = Book.objects.all() serializer_class = BookSerializers
3. 三大组件总结
1.笔记
3 def dispatch(): #一 初始化操作 # (1) 构建新的request: self.request=self.initial_request() # self.request._request # self.request.GET # self.request.data # (2) 执行组件 # 认证,权限,频率 # 认证:request.user self.initial(request, *args, **kwargs) ==== # 认证组件 self.perform_authentication(request) ==== request.user ===== for authenticator in self.authenticators: # [TokenAuth(),] try: user_auth_tuple = authenticator.authenticate(self) except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return # 权限组件 self.check_permissions(request) =========== for permission in self.get_permissions(): if not permission.has_permission(request, self): self.permission_denied( request, message=getattr(permission, 'message', None) ) # 频率组件 self.check_throttles(request) ============= for throttle in self.get_throttles(): # [VisitRateThrottle(),] if not throttle.allow_request(request, self): self.throttled(request, throttle.wait()) # 受限制 # 分发 if request.method.lower() in self.http_method_names: handler = getattr(self,request.method.lower(), self.http_method_not_allowed) response = handler(request, *args, **kwargs) return response
2.代码
urls
"""restdemo URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.2/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path from django.urls import re_path # 正则表达式的 from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('publishes/', views.PublishView.as_view()), # view(request)====> APIView:dispatch() re_path(r'publishes/(?P<pk>d+)/$', views.PublishDetailView.as_view(),name="detailPublish"), path('books/', views.BookView.as_view()), re_path(r'books/(d+)/$', views.BookDetailView.as_view()), # path('authors/', views.AuthorView.as_view()), # re_path(r'authors/(?P<pk>d+)/$', views.AuthorDetailView.as_view()), path('authors/', views.AuthorView.as_view({"get":"list","post":"create"}),name="book_list"), re_path(r'authors/(?P<pk>d+)/$', views.AuthorView.as_view({ "get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy" }),name="book_detail"), path('login/',views.LoginView.as_view()) ]
models
from django.db import models # Create your models here. class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) type_choices = ((1,"普通用户"),(2,'SVip'),(3,'SSVip')) user_type = models.IntegerField(choices=type_choices,default=1) class Token(models.Model): user = models.OneToOneField("user",on_delete=models.CASCADE) token = models.CharField(max_length=128) def __str__(self): return self.token class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish",on_delete=models.CASCADE) authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): # return self.name return self.email class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name