码迷,mamicode.com
首页 > 其他好文 > 详细

Django Rest Framework

时间:2019-01-31 00:21:23      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:数字   mod   执行   课程   流程   clu   指定   注意   tail   

?基于Django

先创建一个django项目,在项目中创建一些表,用来测试rest framework的各种组件

models.py

class UserInfo(models.Model):
    """用户信息表"""
    user = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)


class UserToken(models.Model):
    """用户token表"""
    user = models.OneToOneField(to="UserInfo", on_delete=models.CASCADE)
    token = models.CharField(max_length=64)


class Courses(models.Model):
    """
    课程表
    """
    name = models.CharField(verbose_name="课程名称", max_length=32)
    course_img = models.CharField(verbose_name="课程图片", max_length=64)
    level_choices = (
        (1, "初级"),
        (2, "中级"),
        (3, "高级"),
    )
    level = models.IntegerField(verbose_name="难度", choices=level_choices, default=1)

    def __str__(self):
        return self.name


class CourseDetail(models.Model):
     """课程详细表"""
     course = models.OneToOneField(to="Courses", on_delete=models.CASCADE)
     slogan = models.CharField(verbose_name="口号", max_length=255)
     why = models.CharField(verbose_name="为什么要学", max_length=255)
     recommend_courses = models.ManyToManyField(verbose_name="推荐课程", to="Courses",
                                                related_name="rc")  # related_name设置反向查询的字段,有多个关联时指定某个字段进行反向查询

    def __str__(self):
         return "课程详细:" + self.course.title



class Chapter(models.Model):
    """
    课程章节表
    """
    num = models.IntegerField(verbose_name="章节")
    name = models.CharField(verbose_name="章节名称", max_length=32)
    course = models.ForeignKey(verbose_name="所属课程", to="Courses", related_name=coursechapters, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

  

urls.py

from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
    path(admin/, admin.site.urls),
    re_path(r^api/(?P<version>\w+)/, include("api.urls")),
]

api/urls.py

from django.urls import re_path
from api.views import courses, account, micro

urlpatterns = [
re_path(r‘^courses/$‘, courses.CoursesView.as_view({"get": "list"})),
re_path(r‘^courses/(?P<pk>\d+)/‘, courses.CoursesView.as_view({"get": "retrieve"})),

re_path(r‘^micro/$‘, micro.MicroView.as_view({"get": "list"})),

re_path(r‘^login/$‘, account.LoginView.as_view()),
]

 

?基本流程

请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发不同的方法,返回不同的内容

url.py

1 from django.conf.urls import url, include
2 from api.views import TestView
3  
4 urlpatterns = [
5     url(r^test/, TestView.as_view()),
6 ]

views.py

 1 from rest_framework.views import APIView
 2 from rest_framework.response import Response
 3  
 4  
 5 class TestView(APIView):
 6     def dispatch(self, request, *args, **kwargs):
 7         """
 8         请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发 get/post/put等方法
 9          
10         注意:dispatch方法有好多好多的功能
11         """
12         return super().dispatch(request, *args, **kwargs)
13  
14     def get(self, request, *args, **kwargs):
15         return Response(GET请求,响应内容)
16  
17     def post(self, request, *args, **kwargs):
18         return Response(POST请求,响应内容)
19  
20     def put(self, request, *args, **kwargs):
21         return Response(PUT请求,响应内容)

?认证组件

给micro添加需要认证才能访问的权限

micro.py

# _*_ coding=utf-8 _*_
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin
from api.auth.auth import MicroAuth


class MicroView(ViewSetMixin, APIView):
    # 给micro添加认证后才能访问的组件
    authentication_classes = [MicroAuth]

    def list(self, request, *args, **kwargs):
        ret = {code: 1000, data: 学习中心}

        return Response(ret)

auth.py

# _*_ coding=utf-8 _*_
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from api.models import *


class MicroAuth(BaseAuthentication):
    """从token表读取token进行认证"""
    def authenticate(self, request):
        token = request.query_params.get(token)
        obj = UserToken.objects.filter(token=token).first()
        if not obj:
            raise AuthenticationFailed({code: 10001, error: 认证失败})
        return (obj.user.user, obj)

全局设置:

上述操作中均是对单独视图进行特殊配置,如果想要对全局进行配置,则需要再配置文件中写入即可

?访问频率控制

给course添加频率限制,同一个IP,60秒内访问不超过3次

?使用自定义类进行访问频率控制,继承BaseThrottle类

myThrottle.py
import time
from rest_framework.throttling import BaseThrottle


class MyThrottle(BaseThrottle):
    """IP访问频率组件
    限制60秒内访问3次"""

    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        current_time = time.time()

        ip = request.META.get(REMOTE_ADDR)
        print(ip)

        if ip not in visit_code:
            # 如果是第一次访问就把此ip的访问时间存入visit_code中,返回True,不限制
            visit_code[ip] = [current_time, ]
            return True

        # 如果不是第一次访问,就获取其ip的访问时间[time1,time2..]
        history = visit_code.get(ip)
        self.history = history
        # print(history,visit_code)

        while history and history[-1] < current_time - 60:
            # 判断第一次访问时间和当前时间是否超过60s,超过则删除
            history.pop()

        if len(history) < 3:
            # history里面的元素小于3个则把当前时间添加进去,方法True
            history.insert(0, current_time)
            return True
        # else:  # 可以不写
        #     return False

    def wait(self):
        """需要等待多少时间才能访问"""
        current_time = time.time()
        return 60 - (current_time - self.history[-1])

在CoursesView类添加访问频率组件

class CoursesView(ViewSetMixin, APIView):
    # 频率访问组件
    throttle_classes = [MyThrottle,]

?使用rest framework内置频率控制组件

myThrottle.py
from rest_framework.throttling import  SimpleRateThrottle


class VisitThrottle(SimpleRateThrottle):
    """内置ip频率组件,需要在settings里面设置参数"""
    scope = "visit_rate"

    def get_cache_key(self, request, view):
        return self.get_ident(request)

settings.py

REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_CLASSES": ["api.myThrottle.VisitThrottle", ],
    "DEFAULT_THROTTLE_RATES": {
        "visit_rate": "5/m",
        # 这个参数就是频率类中定义的那个参数scope, 其中第一个数字5表示5次,
        # 后面的m表示一分钟,还有s,一秒, h, 一小时, d, 一天
    }
}

 



 

Django Rest Framework

标签:数字   mod   执行   课程   流程   clu   指定   注意   tail   

原文地址:https://www.cnblogs.com/zivli/p/10339945.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!