django中的缓存 单页面缓存,局部缓存,全站缓存 跨域问题的解决

一、缓存

介绍:
在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.
当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力.
缓存是将一些常用的数据保存内存或者memcache中,在一定的时间内有人来访问这些数据时,则不再去执行数据库及渲染等操作,而是直接从内存或memcache的缓存中去取得数据,然后返回给用户.

几种缓存方式:
1、开发调试缓存
2、内存缓存
3、文件缓存
4、数据库缓存
5、缓存到redis

1、开发调试(此模式为开发调试使用,实际上不执行任何操作)
CACHES = {
 'default': {
  'BACKEND': 'django.core.cache.backends.dummy.DummyCache',  # 缓存后台使用的引擎
  'TIMEOUT': 300,            # 缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)
  'OPTIONS':{
   'MAX_ENTRIES': 300,          # 最大缓存记录的数量(默认300)
   'CULL_FREQUENCY': 3,          # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
  },
 }
}


2、内存缓存(将缓存内容保存至内存区域中)
CACHES = {
 'default': {
  'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',  # 指定缓存使用的引擎
  'LOCATION': 'unique-snowflake',         # 写在内存中的变量的唯一值 
  'TIMEOUT':300,             # 缓存超时时间(默认为300秒,None表示永不过期)
  'OPTIONS':{
   'MAX_ENTRIES': 300,           # 最大缓存记录的数量(默认300)
   'CULL_FREQUENCY': 3,          # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
  }  
 }
}

3、文件缓存(把缓存数据存储在文件中)
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)
  }
 }   
}


4、数据库缓存
CACHES = {
 'default': {
  'BACKEND': 'django.core.cache.backends.db.DatabaseCache',  # 指定缓存使用的引擎
  'LOCATION': 'cache_table',          # 数据库表    
  'OPTIONS':{
   'MAX_ENTRIES': 300,           # 最大缓存记录的数量(默认300)
   'CULL_FREQUENCY': 3,          # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
  }  
 }   
}


需要注意:创建缓存的数据库表使用的语句:
python manage.py createcachetable

 

缓存的粒度:

全站缓存   来的请求所需要的所有数据全部缓存
单页面缓存   单独一个页面所需的数据缓存起来
局部缓存    页面中某个位置的数据缓存起来

 

缓存的使用:

1.1、单页面的缓存:在视图函数上加上一个装饰器即可

from django.views.decorators.cache import cache_page
import time
@cache_page(10)   # 设置超时时间
def test(request):
    ctime = time.time()
    return render(request,'test.html',locals())

需要注意,在settings里配置一下:
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',  # 指定缓存使用的引擎
        'LOCATION': 'C:\cache_location',  # 指定缓存的路径
        'TIMEOUT': 300,  # 缓存超时时间(默认为300秒,None表示永不过期)
        'OPTIONS': {
            'MAX_ENTRIES': 300,  # 最大缓存记录的数量(默认300)
            'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
        }
    }
}



1.2 cbv下实现单页面缓存
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
import time
@method_decorator(cache_page(5),name='dispatch')
class ShowTime(APIView):
def get(self,request):
ctime = time.strftime('%Y-%m-%d %H:%M:%S')
return render(request,'show_time.html',{'ctime':ctime})



2、局部缓存 from django.core.cache import cache import time def test(request): ctime = time.time() return render(request,'test.html',{'time':ctime}) 虽然与单页面的settings配置是一样的,但在模板文件里存在一定的差异性。 模板层: {% load cache %} {% time %} #这部分的内容没有被缓存 {% cache 5 'test'%} #第一个参数表示缓存时间,第二个参数是key值(取缓存的时候,需要根据key值取) 当前时间:{{ time }} # 这部分的数据被缓存 {% endcache %} 3、全站缓存 需要在settings里配置两个中间件,一个在最上方,一个在最下方 'django.middleware.cache.UpdateCacheMiddleware', # 重写了process_response ''这里的是其他的中间件'' 'django.middleware.cache.FetchFromCacheMiddleware' # 重写了process_request 同时还需要配置超时时间,同样在settings里配置 CACHE_MIDDLEWARE_SECONDS = 5 超时时间设定为5秒 需要注意:不需要配置CACHES了! 缓存的高级用法: 对于前后端分离的项目: cache.set('test_data',{'name':'michael','age':18},5) #对应的key为 test_data,数据位字典里的数据,超时时间为5秒 cache.get('test_data') # 取对应的缓存数据

 

二、跨域

跨域的产生是由于浏览器的同源策略,介绍下:
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

何为跨域:

通常情况下,A网页访问B服务器资源时,不满足以下三个条件其一就是跨域访问
1. 协议不同
2. 端口不同
3. 主机不同

跨域时,后端其实已经拿到前端发送的请求了,只是在返回数据时被拦截了!!!


解决方案:CORS(跨域资源共享)

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。


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


两种请求详解:

只要满足以下两大请求的,就是简单请求:

(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
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”
     => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
        Access-Control-Request-Method
     => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
        Access-Control-Request-Headers


支持跨域,简单请求

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

支持跨域,复杂请求

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

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

 

简单请求:

视图层:
from django.shortcuts import HttpResponse
def test1(request):
    print(request.method)
    bon = HttpResponse('ok')
    return bon

中间件:
class CorsMiddleWare(MiddlewareMixin):
    def process_response(self,request,response):
        if request.method == 'GET':
            response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8001"
        return response

另外一个端口的django下的模板层:
<script>
    $('#btn').click(function () {
        alert(111)
        $.ajax({
            url:'http://127.0.0.1:8000/test1/',
            type:'get',
            data:{'name':'micahel'},
            {#contentType:'application/json',#}
            success:function (datas) {
                console.log(datas)
            }
        })
    })
</script>

 

非简单请求:

视图层:
在简单的函数下:
from django.shortcuts import HttpResponse
def test1(request):
    print(request.method)   # 会打印两次 一次为OPTIONS,另一次为前端的请求方式
    bon = HttpResponse('ok')
    return bon

中间件:
from django.utils.deprecation import MiddlewareMixin

class CorsMiddleWare(MiddlewareMixin):
    def process_response(self, request, response):
        if request.method == 'OPTIONS':
            print(request)  # <WSGIRequest: OPTIONS '/test1/'>
            print(response) #  <HttpResponse status_code=200, "text/html; charset=utf-8">
            response["Access-Control-Allow-Headers"] = "Content-Type"
        if request.method == 'POST':
            print(request)  # <WSGIRequest: POST '/test1/'>
            print(request.POST)  # <QueryDict: {}> 因为我传过来的数据是json类型的
            print(request.body)  # b'name=micahel'  json类型的数据在request.body里面
        response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8001"
        return response


另外一个端口下的模板层:
<script>
    $('#btn').click(function () {
        alert(111)
        $.ajax({
            url:'http://127.0.0.1:8000/test1/',
            type:'post',
            data:{'name':'micahel'},
            contentType:'application/json',
            success:function (datas) {
                console.log(datas)
            }
        })
    })
</script>


待续:在cbv下实现跨域 !!! 因为走了一次预检,所以第一次的method = options ,第二次为 post ,所以可考虑到cbv继承view,在其内部定义一个options方法即可!
不过在实际操作开发过程中,在视图类中不会写options方法,而是直接在中间件里完成即可!


 

-redis的安装和简单使用
-内存数据库
-Redis-x64-3.2.100---》mysql
-redis-desktop-manager-0.9.3.817----》navcate
-安装完后
-redis-server 服务端
-redis-cli 客户端

 

转载于:https://www.cnblogs.com/changwenjun-666/p/11153946.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值