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 客戶端

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM