Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 550|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-8-29 12:40:14 | 显示全部楼层 |阅读模式
    一、缓存
    
    介绍:
    在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.
    当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力.
    缓存是将一些常用的数据保存内存或者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 客户端

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-29 08:09 , Processed in 0.067738 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表