• 版本控制 django缓存 跨域 redis


    一、版本控制:

    1、内置的类:

    QueryParameterVersioning, # 基于get传参的方式
    eg:/users?version=v1
    AcceptHeaderVersioning,# 基于请求头的
    eg:Accept: application/json;   Accept为关键字
    NamespaceVersioning, # 基于名称空间的
    eg:v1.example.com
    URLPathVersioning   # 基于正则的方式(推荐)
    eg:/v1/users/
    View Code

     2、局部使用:

    在视图类中配置

    如:versioning_class=URLPathVersioning   #单个项目只能设置一种方法  所以此处非列表

    3、全局使用:在settings中配置:

    REST_FRAMEWORK = {
        'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.QueryParameterVersioning',
        'DEFAULT_VERSION': 'v1',            # 默认版本(从request对象里取不到,显示的默认值)
        'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本
        'VERSION_PARAM': 'version'          # URL中获取值的key
    }
    View Code

    二、django缓存

    1、目的:为了提高网站的并发量

    2、djago缓存的三种粒度六种缓存方式

    2.1、六种缓存方式:

    a、开发调试缓存

    b、内存缓存

    c、文件缓存

    d、数据库缓存

    e、Memcache缓存(使用python-memcached模块)

    f、Memcache缓存(使用pylibmc模块)

    经常使用的有文件缓存和Mencache缓存

    2.2、三种粒度:

    a、全站缓存

    b、单页面缓存

    c、页面中局部缓存

    3、缓存是的使用:(文件缓存举例:)

    其他缓存配置请参考:https://www.cnblogs.com/liuqingzheng/articles/9803351.html

    3.1 在settings中配置(缓存方式:文件)

    CACHES = {
     'default': {
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎
             'LOCATION': '/var/tmp/django_cache',        #指定缓存的路径
             'TIMEOUT':300,              #缓存超时时间(默认为300秒,None表示永不过期)
             'OPTIONS':{
                      'MAX_ENTRIES': 300,            # 最大缓存记录的数量(默认300)
                              'CULL_FREQUENCY': 3,           # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
                          }
                         }   
                        }
    View Code

    3.2、使用缓存:

    3.2.1、使用单页面缓存(使用装饰器):

    视图:

    from django.views.decorators.cache import cache_page
    import time
    from .models import *
    
    @cache_page(15)          #超时时间为15秒
    def index(request):
      t=time.time()      #获取当前时间
      bookList=Book.objects.all()
      return render(request,"index.html",locals())
    View Code

    html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>当前时间:-----{{ t }}</h3>
    
    <ul>
        {% for book in bookList %}
           <li>{{ book.name }}--------->{{ book.price }}$</li>
        {% endfor %}
    </ul>
    
    </body>
    </html>
    View Code

    3.2.2、页面局部缓存:

    视图:

    from django.views.decorators.cache import cache_page
    import time
    from .models import *
    def index(request):
         t=time.time()      #获取当前时间
         bookList=Book.objects.all()
         return render(request,"index.html",locals())
    View Code

    html:

    {% load cache %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
     <h3 style="color: green">不缓存:-----{{ t }}</h3>
    
    {% cache 2 'name' %}
     <h3>缓存:-----:{{ t }}</h3>
    {% endcache %}
    
    </body>
    </html> 
    View Code

    3.2.3、全站缓存:

    通过中间件控制,判断缓存是否存在,若不存在,则通过中间件将其全部缓存到django的缓存中

    MIDDLEWARE_CLASSES = (
        'django.middleware.cache.UpdateCacheMiddleware',   #响应HttpResponse中设置几个headers
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'django.middleware.security.SecurityMiddleware',
        'django.middleware.cache.FetchFromCacheMiddleware',   #用来缓存通过GET和HEAD方法获取的状态码为200的响应
    
    )
    
    
    CACHE_MIDDLEWARE_SECONDS=10  # 用来控制时间的配置   单位为s
    View Code

    视图函数:

    from django.views.decorators.cache import cache_page
    import time
    from .models import *
    
    
    def index(request):
    
         t=time.time()      #获取当前时间
         bookList=Book.objects.all()
         return render(request,"index.html",locals())
    
    def foo(request):
        t=time.time()      #获取当前时间
        return HttpResponse("HELLO:"+str(t))
    View Code

    html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3 style="color: green">当前时间:-----{{ t }}</h3>
    
    <ul>
        {% for book in bookList %}
           <li>{{ book.name }}--------->{{ book.price }}$</li>
        {% endfor %}
    </ul>
    
    </body>
    </html>
    View Code

    4、补充,缓存存储的数据格式:

    -缓存存储的数据格式
    unique-snowflake={
        index:asdfafasfasf,
        test:aerafdgerytwrega,
        'ttt':saefasfaefqwe,
        'yyy':asdfasfdsad,
    }                
    View Code

    三、跨域问题:

    IP 端口 协议三者有一个不同就是跨域

    解决方法:跨域资源共享

    1、跨域资源共享(CORS)简介:

    CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

    因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

    2、CORS基本流程

    浏览器将CORS请求分成两类:简单请求(simple request)非简单请求(not-so-simple request)。
    浏览器发出CORS简单请求只需要在头信息之中增加一个Origin字段。
    浏览器发出CORS非简单请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

    3、CORS两种请求详解:

    (1) 请求方法是以下三种方法之一:
        HEAD
        GET
        POST
    (2)HTTP的头信息不超出以下几种字段:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
    
    * 简单请求和非简单请求的区别?
    
       简单请求:一次请求
       非简单请求:两次请求:一次是OPTIONS预检请求,预检请求同意我发,我再发起第二次真实请求,一次是真实的请求
            以后处理跨域问题(可以用第三方的django-cors-headers),即在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。
    * 关于“预检” - 请求方式:OPTIONS - “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息 - 如何“预检” => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过 Access-Control-Request-Method => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过 Access-Control-Request-Headers

    支持跨域,简单请求

    服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

    支持跨域,复杂请求

    由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

    • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
    • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers

    例:

    class MyMiddleware(MiddlewareMixin):
        def process_response(self,request,response):
        #处理了简单请求
        response['Access-Control-Allow-Origin'] = '*'
        #处理非简单请求
        if request.method=='OPTIONS':
        response['Access-Control-Allow-Headers']='*'
        # response['Access-Control-Allow-Methods']='PUT,PATCH'
        response['Access-Control-Allow-Methods']='*'
    
            return response    
    View Code

    四、redis数据库:

    1、数据库的安装:https://www.cnblogs.com/liuqingzheng/p/9831331.html

    2、redis,mongodb:非关系型数据库/nosql
                -redis存储在内存中
                -mongodb存储在硬盘上

    3、redis一般用来
                a、做缓存
                b、session数据
                c、游戏排行榜
                d、对速度要求比较高的数据的存储
                e、做消息队列

    4、redis是key-value的存储,支持持久化,像py中的字典,有5大数据类型:
                a、字符串
                b、列表
                c、字典
                d、集合
                e、有序集合
                redis={
                    k1:'123',           字符串
                    k2:[1,2,3,4],      列表/数组
                    k3:{1,2,3,4}      集合
                    k4:{name:lqz,age:12}  字典/哈希表
                    k5:{('lqz',18),('egon',33)}  有序集合
            }

    5、比较redis和Memcached
                a、redis 支持5大数据类型
                b、redis支持持久化
                c、单线程,单进程,速度是非常快
                d、Memcached不能持久化,只支持字符串

    6、string操作:

    set(name, value, ex=None, px=None, nx=False, xx=False)
    #在Redis中设置值,默认,不存在则创建,存在则修改
    参数:
        # ex,过期时间(秒)
        # px,过期时间(毫秒)
        # nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
        # xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
    
    setnx(name, value)
    #设置值,只有name不存在时,执行设置操作(添加),如果存在,不会修改
    
    setex(name, time, value)
    # 设置值
    # 参数:
        # time,过期时间(数字秒 或 timedelta对象)
    
    psetex(name, time_ms, value)
    # 设置值
    # 参数:
        # time_ms,过期时间(数字毫秒 或 timedelta对象
    
    mset(*args, **kwargs)
    #批量设置值
    #如:
       # mset(k1='v1', k2='v2')
       #
       # mget({'k1': 'v1', 'k2': 'v2'})
    
    get(name)
    #获取值
    
    mget(keys, *args)
    #批量获取
    #如:
        #mget('k1', 'k2')
        #
        #r.mget(['k3', 'k4'])
    
    getset(name, value)
    #设置新值并获取原来的值
    
    getrange(key, start, end)
    # 获取子序列(根据字节获取,非字符)
    # 参数:
        # name,Redis 的 name
        # start,起始位置(字节)
        # end,结束位置(字节)
    # 如: "刘清政" ,0-3表示 "刘"
    
    setrange(name, offset, value)
    # 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
    # 参数:
        # offset,字符串的索引,字节(一个汉字三个字节)
        # value,要设置的值
    
    setbit(name, offset, value)
    # 对name对应值的二进制表示的位进行操作
     
    # 参数:
        # name,redis的name
        # offset,位的索引(将值变换成二进制后再进行索引)
        # value,值只能是 1 或 0
     
    # 注:如果在Redis中有一个对应: n1 = "foo",
            那么字符串foo的二进制表示为:01100110 01101111 01101111
        所以,如果执行 setbit('n1', 7, 1),则就会将第7位设置为1,
            那么最终二进制则变成 01100111 01101111 01101111,即:"goo"
    
    getbit(name, offset)
    # 获取name对应的值的二进制表示中的某位的值 (0或1)
    
    bitcount(key, start=None, end=None)
    # 获取name对应的值的二进制表示中 1 的个数
    # 参数:
        # key,Redis的name
        # start,位起始位置
        # end,位结束位置
    
    bitop(operation, dest, *keys)
    # 获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值
     
    # 参数:
        # operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(异或)
        # dest, 新的Redis的name
        # *keys,要查找的Redis的name
     
    # 如:
        bitop("AND", 'new_name', 'n1', 'n2', 'n3')
        # 获取Redis中n1,n2,n3对应的值,然后讲所有的值做位运算(求并集),然后将结果保存 new_name 对应的值中
    
    strlen(name)
    # 返回name对应值的字节长度(一个汉字3个字节)
    
    incr(self, name, amount=1)
    # 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
    # 参数:
        # name,Redis的name
        # amount,自增数(必须是整数)
    # 注:同incrby
    
    incrbyfloat(self, name, amount=1.0)
    # 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
     
    # 参数:
        # name,Redis的name
        # amount,自增数(浮点型)
    
    decr(self, name, amount=1)
    # 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。
     
    # 参数:
        # name,Redis的name
        # amount,自减数(整数)
    
    append(key, value)
    # 在redis name对应的值后面追加内容
     
    # 参数:
        key, redis的name
        value, 要追加的字符串

    7、django中使用redis

    方式一:(通过导入模块来实现单例)

    --redis_pool.py

    import redis
    POOL = redis.ConnectionPool(host='127.0.0.1', port=6379,password='1234',max_connections=1000)
    View Code

    视图函数中使用:

    import redis
    from django.shortcuts import render,HttpResponse
    from utils.redis_pool import POOL
    
    def index(request):
        conn = redis.Redis(connection_pool=POOL)
        conn.hset('kkk','age',18)
    
        return HttpResponse('设置成功')
    def order(request):
        conn = redis.Redis(connection_pool=POOL)
        conn.hget('kkk','age')
    
        return HttpResponse('获取成功')
    View Code

    方式二:

    安装django-redis模块

    settings中

    # redis配置
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # "PASSWORD": "123",
            }
        }
    }
    View Code

    视图函数:

    from django_redis import get_redis_connection
    conn = get_redis_connection('default')
    print(conn.hgetall('xxx'))
    View Code

    附:https://www.cnblogs.com/liuqingzheng/articles/9833534.html#_label3

  • 相关阅读:
    Visual Studio一直弹出“未将对象引用设置到对象的实例”对话框的处理
    C#如何将十六进制数字符串转byte[]?
    steam游戏存档迁移
    Java实现行列式计算
    Python中单引号、双引号、三引号的区别
    git基本使用方法
    windows(hexo)使用git时出现:warning: LF will be replaced by CRLF
    steam相关插件
    linux的后台运行相关命令
    Ubuntu下启动/重启/停止apache服务器
  • 原文地址:https://www.cnblogs.com/peng-zhao/p/10638546.html
Copyright © 2020-2023  润新知