Webサーバーのプロセスは任意のタイミングで再起動します。このため、グローバル変数になにかを記録しておいて使い回すというやり方は出来ません。
提示されたコードであれば以下の様に書きます(accessCountは使ってないようなので一旦無視)。
Python
1from shop.models import Product
2from django.shortcuts import render
3
4
5def viewProductList(request):
6
7 productList = Product.object.all()
8 return render(request, "viewProductList.html", productList)
このページがすぐには更新されないのでproductListを何度も再取得したくない、ということであれば、以下のようにview関数の結果自体をcacheします。
Python
1from django.views.decorators.cache import cache_page
2from shop.models import Product
3from django.shortcuts import render
4
5
6def get_products():
7
8@cache_page(60 * 15) # cache in 15 minutes
9def viewProductList(request):
10 productList = Product.object.all()
11 return render(request, "viewProductList.html", productList)
いやいや、ページ自体は再描画が必要で、productListの再取得だけ減らしたい、ということであれば、cacheを以下のように利用します。
Python
1import functools
2
3from shop.models import Product
4from django.shortcuts import render
5
6
7@functools.lru_cache()
8def get_products():
9 return list(Product.object.all())
10
11
12def viewProductList(request):
13 return render(request, "viewProductList.html", productList)
ただし、このキャッシュは時間で破棄されず、プロセスが生きている間ずっと効いてしまいます。最初に提示されていたコードと同じ挙動なので、これもありなのかもしれません。
時間でキャッシュしたければ、Djangoのキャッシュ機構を使えます。
Python
1from django.core.cache import cache
2
3from shop.models import Product
4from django.shortcuts import render
5
6
7def viewProductList(request):
8 productList = cache.get('productList')
9 if productList is None:
10 productList = list(Product.object.all())
11 cache.set('productList', productList, 60 * 15) # cache in 15 minutes
12
13 return render(request, "viewProductList.html", productList)
Djangoのcacheはプロセスのメモリ内だったり、外部のデータストアだったり、設定次第でデータを置く場所を決められます。このため、memcachedなどの外部データストアにキャッシュを置けば、Webサービスが複数のプロセスで動作している場合にもキャッシュを共有できます。
最初に除外した、accessCountもcacheに置いてアクセス毎に1つ値を上げる、という使い方ができるようになります。
ここまで紹介したcacheというものは、どれも「一時的なもの」でしかないので、何かのタイミングで消えてしまいます。productListは時間で消えてくれないと永遠に最初に取得した商品一覧しか表示出来ないので時間で消したいですが、accessCountは増加し続けて欲しいので消えられると困る、といったデータの特性によってキャッシュが良いのかDBが良いのかを判断して置き場所を決めることになります。
使い方が楽そうなのは、cacheバックエンドをRedisにして、productListは時間でキャッシュを消す設定で使い、accessCountは永続データとしてキャッシュタイムアウトなしで保存する、という方法でしょう。ただし、外部データストアのサーバーを起動する必要があるので、準備の手間はちょっと増えます。
参考: