django 之(四) --- 级联|截流
登陆注册
登陆注册实现
- settings.py
- # redis配置
- CACHES = {
- "default": {
- "BACKEND": "django_redis.cache.RedisCache",
- "LOCATION": "redis://127.0.0.1:6379/1",
- "TIMEOUT": 60 * 60 * 24,
- "OPTIONS": {
- "CLIENT_CLASS": "django_redis.client.DefaultClient",
- }
- }
- }
- App/models.py
- from django.db import models
- class UserModel(models.Model):
- u_name = models.CharField(max_length=16, unique=True)
- u_password = models.CharField(max_length=256)
- def __str__(self):
- return self.u_name
- App/serializers.py
- from rest_framework import serializers
- from App.models import UserModel, Address
- class UserSerializer(serializers.HyperlinkedModelSerializer):
- class Meta:
- model = UserModel
- fields = ('url', 'id', 'u_name', 'u_password', 'address_list')
- App/views.py
- import uuid
- from django.core.cache import cache
- from rest_framework import exceptions
- from rest_framework.generics import CreateAPIView, RetrieveAPIView
- from rest_framework.response import Response
- from App.models import UserModel
- from App.serializers import UserSerializer
- # 继承自CreateAPIView。。exceptions框架封装的状态码变量包文件
- class UsersAPIView(CreateAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- # 重写post,获取其action动作
- def post(self, request, *args, **kwargs):
- action = request.query_params.get('action')
- if action == "login": # 登陆动作
- u_name = request.data.get('u_name')
- u_password = request.data.get('u_password')
- try:
- user = UserModel.objects.get(u_name=u_name)
- if user.u_password != u_password:
- raise exceptions.AuthenticationFailed
- token = uuid.uuid4().hex
- cache.set(token, user.id, timeout=60 * 60 * 24)
- data = {
- 'msg': 'login success',
- 'status': 200,
- 'token': token
- }
- return Response(data)
- except UserModel.DoesNotExist:
- raise exceptions.NotFound
- elif action == "register": # 注册动作
- return self.create(request, *args, **kwargs)
- else:
- raise exceptions.ParseError
- # 继承自RetrieveAPIView。
- class UserAPIView(RetrieveAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- urls.py 和 App/urls.py
- from django.conf.urls import url, include
- urlpatterns = [
- url(r'^app/', include('App.urls')),
- ]
- #------------------------------------------------------------------------------------------
- from django.conf.urls import url
- from App import views
- urlpatterns = [
- url(r'^users/$', views.UsersAPIView.as_view()),
- # 继承自序列化HyperlinkedModelSerializer。需要加详情信息的url
- url(r'^users/(?P<pk>\d+)/$', views.UserAPIView.as_view(), name='usermodel-detail'),
- ]
用户地址
登陆用户对地址添加
- App/models.py
- from django.db import models
- class UserModel(models.Model):
- u_name = models.CharField(max_length=16, unique=True)
- u_password = models.CharField(max_length=256)
- def __str__(self):
- return self.u_name
- class Address(models.Model):
- a_address = models.CharField(max_length=128)
- a_user = models.ForeignKey(UserModel, related_name='address_list', null=True, blank=True)
- def __str__(self):
- return self.a_address
- App/serializers.py
- from rest_framework import serializers
- from App.models import UserModel, Address
- class AddressSerializer(serializers.HyperlinkedModelSerializer):
- class Meta:
- model = Address
- fields = ('url', 'id', 'a_address')
- class UserSerializer(serializers.HyperlinkedModelSerializer):
- address_list = AddressSerializer(many=True, read_only=True)
- class Meta:
- model = UserModel
- fields = ('url', 'id', 'u_name', 'u_password', 'address_list')
- App/views.py
- import uuid
- from django.core.cache import cache
- from rest_framework import exceptions
- from rest_framework.generics import CreateAPIView, RetrieveAPIView
- from rest_framework.response import Response
- from rest_framework import viewsets
- from App.auth import LoginAuthentication
- from App.models import UserModel, Address
- from App.permissions import RequireLoginPermission
- from App.serializers import UserSerializer, AddressSerializer
- # 继承自CreateAPIView。。exceptions框架封装的状态码变量包文件
- class UsersAPIView(CreateAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- # 重写post,获取其action动作
- def post(self, request, *args, **kwargs):
- action = request.query_params.get('action')
- if action == "login": # 登陆动作
- u_name = request.data.get('u_name')
- u_password = request.data.get('u_password')
- try:
- user = UserModel.objects.get(u_name=u_name)
- if user.u_password != u_password:
- raise exceptions.AuthenticationFailed
- token = uuid.uuid4().hex
- cache.set(token, user.id, timeout=60 * 60 * 24)
- data = {
- 'msg': 'login success',
- 'status': 200,
- 'token': token
- }
- return Response(data)
- except UserModel.DoesNotExist:
- raise exceptions.NotFound
- elif action == "register": # 注册动作
- return self.create(request, *args, **kwargs)
- else:
- raise exceptions.ParseError
- # 继承自RetrieveAPIView
- class UserAPIView(RetrieveAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- class AddressAPIView(viewsets.ModelViewSet):
- serializer_class = AddressSerializer
- queryset = Address.objects.all()
- # 登陆认证。判断用户是否登陆成功的
- authentication_classes = (LoginAuthentication,)
- # 权限认证。只有登陆的用户才有权限
- permission_classes = (RequireLoginPermission,)
- App/auth
- # 登陆认证。判断用户是否是登陆状态、是否是合法用户
- from django.core.cache import cache
- from rest_framework.authentication import BaseAuthentication
- from App.models import UserModel
- # 登陆认证器。继承自BaseAuthentication
- class LoginAuthentication(BaseAuthentication):
- def authenticate(self, request):
- try:
- token = request.query_params.get('token')
- user_id = cache.get(token)
- user = UserModel.objects.get(pk=user_id)
- return user, token
- except Exception:
- return
- App/permissions.py
- # 权限认证。只有登陆用户的对象是此模型类的实例才有权限对地址信息进行操作
- from rest_framework.permissions import BasePermission
- from App.models import UserModel
- class RequireLoginPermission(BasePermission):
- # 重写has_permission方法,判断是否有权限
- def has_permission(self, request, view):
- # isinstance判断此用户是否是此模型的实例。如果是返回True;不是返回False
- return isinstance(request.user, UserModel)
- urls.py 和 App/urls.py
- from django.conf.urls import url
- from App import views
- urlpatterns = [
- url(r'^users/$', views.UsersAPIView.as_view()),
- # 继承自序列化HyperlinkedModelSerializer。需要加详情的url
- url(r'^users/(?P<pk>\d+)/$', views.UserAPIView.as_view(), name='usermodel-detail'),
- # 视图类继承自viewsets.ModelViewSet。
- url(r'^address/$', views.AddressAPIView.as_view(
- {
- 'post': 'create', # 参数:post对应create类方法
- 'get': 'list', # 参数:get对应list类方法
- }
- )),
- # 继承自序列化HyperlinkedModelSerializer。需要加详情的url
- url(r'^address/(?P<pk>\d+)/$', views.AddressAPIView.as_view(
- {
- 'get': 'retrieve',
- }
- ), name='address-detail'),
- ]
查询操作
认证登陆用户权限查询
- App/views.py
- import uuid
- from django.core.cache import cache
- from rest_framework import exceptions, status
- from rest_framework.generics import CreateAPIView, RetrieveAPIView
- from rest_framework.response import Response
- from rest_framework import viewsets
- from App.auth import LoginAuthentication
- from App.models import UserModel, Address
- from App.permissions import RequireLoginPermission
- from App.serializers import UserSerializer, AddressSerializer
- # 继承自CreateAPIView。。exceptions框架封装的状态码变量包文件
- class UsersAPIView(CreateAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- # 重写post,获取其action动作
- def post(self, request, *args, **kwargs):
- action = request.query_params.get('action')
- if action == "login": # 登陆动作
- u_name = request.data.get('u_name')
- u_password = request.data.get('u_password')
- try:
- user = UserModel.objects.get(u_name=u_name)
- if user.u_password != u_password:
- raise exceptions.AuthenticationFailed
- token = uuid.uuid4().hex
- cache.set(token, user.id, timeout=60 * 60 * 24)
- data = {
- 'msg': 'login success',
- 'status': 200,
- 'token': token
- }
- return Response(data)
- except UserModel.DoesNotExist:
- raise exceptions.NotFound
- elif action == "register": # 注册动作
- return self.create(request, *args, **kwargs)
- else:
- raise exceptions.ParseError
- # 继承自RetrieveAPIView
- class UserAPIView(RetrieveAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- class AddressAPIView(viewsets.ModelViewSet):
- serializer_class = AddressSerializer
- queryset = Address.objects.all()
- # 登陆认证
- authentication_classes = (LoginAuthentication,)
- # 权限认证
- permission_classes = (RequireLoginPermission,)
- # 重写create。地址信息关联用户
- def create(self, request, *args, **kwargs):
- serializer = self.get_serializer(data=request.data)
- serializer.is_valid(raise_exception=True)
- self.perform_create(serializer)
- headers = self.get_success_headers(serializer.data)
- # 对用户和地址进行绑定操作
- user = request.user
- a_id = serializer.data.get('id')
- address = Address.objects.get(pk=a_id)
- address.a_user = user
- address.save()
- return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
- # 重写list方法。实现get请求时只显示当前用户对应的地址信息的及联操作
- def list(self, request, *args, **kwargs):# 根据用户查询地址信息。其他代码都是源码内容
- queryset = self.filter_queryset(self.queryset.filter(a_user=request.user))
- page = self.paginate_queryset(queryset)
- if page is not None:
- serializer = self.get_serializer(page, many=True)
- return self.get_paginated_response(serializer.data)
- serializer = self.get_serializer(queryset, many=True)
- return Response(serializer.data)
- # 继承自RetrieveAPIView。用户信息查询,只有登陆认证的用户才可以查看自己的信息
- class UserAPIView(RetrieveAPIView):
- serializer_class = UserSerializer
- queryset = UserModel.objects.all()
- 6 authentication_classes = (LoginAuthentication,)
- 7 permission_classes = (RequireLoginPermission,)
- # 判定是本人。登陆认证后,只能查看自己的信息。[限制请求接口:路径里面的参数和用户是同一个用户才可查询]
- def retrieve(self, request, *args, **kwargs):
- if kwargs.get('pk') != str(request.user.id):
- raise exceptions.AuthenticationFailed
- instance = self.get_object()
- serializer = self.get_serializer(instance)
- return Response(serializer.data)
及联查询
- 路由url:http://127.0.0.1:8000/app/users/1/?token=7fc732d30b5e4f5ebfde8e59e1938e22
- App/models.py
- from django.db import models
- class UserModel(models.Model):
- u_name = models.CharField(max_length=16, unique=True)
- u_password = models.CharField(max_length=256)
- def __str__(self):
- return self.u_name
- class Address(models.Model):
- a_address = models.CharField(max_length=128)
- a_user = models.ForeignKey(UserModel, related_name='address_list', null=True, blank=True)
- def __str__(self):
- return self.a_address
- App/serializers.py
- from rest_framework import serializers
- from App.models import UserModel, Address
- class AddressSerializer(serializers.HyperlinkedModelSerializer):
- class Meta:
- model = Address
- fields = ('url', 'id', 'a_address')
- 8 # 及联操作。
- class UserSerializer(serializers.HyperlinkedModelSerializer):
- # 此处变量名要和模型中related_name='address_list'定义的名字对应。
- # 如果模型中没有定义related_name字段,默认系统识别的名字是address_set
- address_list = AddressSerializer(many=True, read_only=True)
- class Meta:
- model = UserModel
- fields = ('url', 'id', 'u_name', 'u_password', 'address_list')
截流控制 [频率控制]
- settings.py 截流注册。配置全局截流,若想对某一个类视图截流,可以在此视图中设置
- # 配置全局截流
- REST_FRAMEWORK = {
- "DEFAULT_THROTTLE_CLASSES": (
- # 限制用户的频率。用户类名
- "App.throttles.UserThrottle",
- # 限制游客的频率:AnonRateThrottle
- ),
- # 限制的【频率
- "DEFAULT_THROTTLE_RATES": {
- "user": "5/m", # 登陆的用户每分钟5次
- }
- }
- App/throttles 自定义截流
- from rest_framework.throttling import SimpleRateThrottle
- from App.models import UserModel
- class UserThrottle(SimpleRateThrottle):
- scope = 'user'
- def get_cache_key(self, request, view):
- if isinstance(request.user, UserModel):
- ident = request.auth
- else:
- ident = self.get_ident(request)
- return self.cache_format % {
- 'scope': self.scope,
- 'ident': ident
- }
HTTP_X_FORWARDED_FOR:获取你的原始IP,通过的普通的代理发送请求的请求;如果获取REMOTE_ADDR获取到的是代理IP
截流器源码分析
节流器
BaseThrottle
allow_request:[抽象未实现]是否允许的请求的核心
get_ident:获取客户端唯一标识
- wait:默认是None
SimpleRateThrottle
get_cache_key:获取缓存标识
get_rate:获取频率
parse_rate:转换频率。num/duration[s、m、h、d]
allow_request:是否允许请求,重写的方法
throttle_success:允许请求,进行请求记录
throttle_failure:不允许请求
wait:还有多少时间之后允许
AnonRateThrottle
get_cache_key:获取缓存key的原则
UserRateThrottle
和上面一模一样
ScopedRateThrottle
和上面一样。多写了从属性中获取频率
django 之(四) --- 级联|截流的更多相关文章
- python学习笔记--Django入门四 管理站点--二
接上一节 python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...
- django第四天(路由别名,django2.x新特性和自定义转换器)
django第四天 路由别名 1.路由别名: 给路由路径命名一个名字 url(r'^login/$',views.login,name = 'login') 2.为什么要用路由别名 ①当路由路径过长时 ...
- Django - Xadmin (四) Filter
Django - Xadmin (四) Filter Filter 功能描述 与 admin 组件中 Filter 功能类似,在展示页面右侧放置一列标签,通过点击这些标签来筛选出该标签相关的数据. 比 ...
- day 68 Django基础四之模板系统
Django基础四之模板系统 本节目录 一 语法 二 变量 三 过滤器 四 标签Tags 五 模板继承 六 组件 七 自定义标签和过滤器 八 静态文件相关 一 语法 模板渲染的官方文档 关 ...
- day 54 Django基础四之模板系统
Django基础四之模板系统 本节目录 一 语法 二 变量 三 过滤器 四 标签Tags 五 模板继承 六 组件 七 自定义标签和过滤器 八 静态文件相关 一 语法 模板渲染的官方文档 关于模 ...
- Django基础四之测试环境和ORM查询
Django基础四之测试环境和ORM查询 目录 Django基础四之测试环境和ORM查询 1. 搭建测试环境 1.1 测试环境搭建方法: 1.2 使用测试环境对数据库进行CURD 1.3 返回Quer ...
- 【Python】Django数据模型、级联删除、级联更新、ER图导出等
在本文中,我们将向读者详细介绍如何在更新和删除父表数据的同时,触发有关子表数据的级联更新和删除操作.您将看到当使用InnoDB表的时候,借助于外键约束就可以轻松搞定这一过程. 一.利用外键约束更新并删 ...
- 小白学习django第四站-关联数据库
使用mysql连接django首先要配置好相关环境 首先在setting.py配置数据库信息(需要现在mysql中创建一个数据库) 在setting.py那个目录的__init__.py文件中写入 之 ...
- Django(四)
一.请求周期 url> 路由 > 函数或类 > 返回字符串或者模板语言? 1.Form表单提交: 提交 -> url > 函数或类中的方法 - .... HttpResp ...
随机推荐
- Object类实现的方法
---恢复内容开始--- 1.Clone 对象浅复制,实现Clonable接口可调用,否则CloneNotSupportedException异常 2.getClass final方法,获得方法运行的 ...
- JavaScript设置和获取cookie
创建 //创建cookie function setCookie(name, value, expires, path, domain, secure) { var cookieText = enco ...
- redis使用例子
package test.iafclub.redis; import java.util.ArrayList; import java.util.HashMap; import java.util.I ...
- P3306 [SDOI2013]随机数生成器
思路:\(BSGS\) 提交:\(1\)次 题解: 原式可以化为\[x_{i+1}+\frac{b}{a-1}=a(x_{i}+\frac{b}{a-1})\mod p\] 这不是等比数列吗? \[x ...
- Oracle 物理结构(四) 文件-控制文件
一.什么是控制文件 控制文件是Oracle数据库中十分重要的文件.Oracle启动时,首先会读取参数文件,读取了参数文件,实例所需要的共享内存和后台进程就可以启动了,这就是数据库实例的nomunt阶段 ...
- LibreOJ #6000. 「网络流 24 题」搭配飞行员
二次联通门 : LibreOJ #6000. 「网络流 24 题」搭配飞行员 /* LibreOJ #6000. 「网络流 24 题」搭配飞行员 二分图最大匹配 Dinic最大流 + 当前弧优化 */ ...
- 卷积理论 & 高维FWT学习笔记
之前做了那么多生成函数和多项式卷积的题目,结果今天才理解了优化卷积算法的实质. 首先我们以二进制FWT or作为最简单的例子入手. 我们发现正的FWT or变换就是求$\hat{a}_j=\sum_{ ...
- yquery-操作样式属性
前几天回家,参加了全国的成人高考,都说学历是找工作的敲门砖,其实一点都不假,尤其是现在的社会竞争力那么强,你不学就会被淘汰.像要过自己想要的生活,就必须努力学习,努力赚钱,买自己想买的,过自己想过的. ...
- APP相关测试工具
名称 描述 性能检测工具 用于对插件CPU.内存.闪退进行测试 接口测试工具 用于对插件本版本内的接口进行上线前的结构检测 自动比对差异 monkey测试工具 对主软件进行稳定性测试 ...
- NMS(非极大值抑制)实现
1.IOU计算 设两个边界框分别为A,B.A的坐标为Ax1,Ax2,Ay1,Ay2,且Ax1 < Ax2,Ay1 < Ay2.B和A类似. 则IOU为A∩B除以A∪B. 当两个边界框有重叠 ...