Static Web sites, in which simple files are served directly to the Web, scale like crazy. But a fundamental tradeoff in dynamic Web sites is, well, theyre dynamic. Each time a user requests a page, the Web server makes all sorts of calculationsfrom database queries, to template rendering, to business logic to create the page that your sites visitor sees. From a processing-overhead perspective, this is quite expensive.
闈欐佺殑缃戠珯鐨勫唴瀹归兘鏄簺绠鍗曠殑闈欐佺綉椤电洿鎺ュ瓨鍌ㄥ湪鏈嶅姟鍣ㄤ笂锛屽彲浠ラ潪甯稿鏄撳湴杈惧埌闈炲父鎯婁汉鐨勮闂噺銆備絾鏄姩鎬佺綉绔欏洜涓烘槸鍔ㄦ佺殑锛屼篃灏辨槸璇存瘡娆$敤鎴疯闂竴涓〉闈紝鏈嶅姟鍣ㄨ鎵ц鏁版嵁搴撴煡璇紝鍚姩妯℃澘锛屾墽琛屼笟鍔¢昏緫鍒版渶缁堢敓鎴愪竴涓綘鎵鐪嬪埌鐨勭綉椤碉紝杩欎竴鍒囬兘鏄姩鎬佸嵆鏃剁敓鎴愮殑銆備粠澶勭悊鍣ㄨ祫婧愮殑瑙掑害鏉ョ湅锛岃繖鏄瘮杈冩槀璐电殑銆
For most Web applications, this overhead isnt a big deal. Most Web applications arent washingtonpost.com or Slashdot; theyre simply small- to medium-sized sites with so-so traffic. But for medium- to high-traffic sites, its essential to cut as much overhead as possible. Thats where caching comes in.
瀵逛簬澶у鏁扮綉缁滃簲鐢ㄦ潵璇达紝杩囪浇骞朵笉鏄ぇ闂銆傚洜涓哄ぇ澶氭暟缃戠粶搴旂敤骞朵笉鏄痺ashingtonpost.com鎴朣lashdot锛涘畠浠氬父鏄緢灏忓緢绠鍗曪紝鎴栬呮槸涓瓑瑙勬ā鐨勭珯鐐癸紝鍙湁寰堝皯鐨勬祦閲忋備絾鏄浜庝腑绛夎嚦澶ц妯℃祦閲忕殑绔欑偣鏉ヨ锛屽敖鍙兘鍦拌В鍐宠繃杞介棶棰樻槸闈炲父蹇呰鐨勩傝繖灏遍渶瑕佺敤鍒扮紦瀛樹簡銆
To cache something is to save the result of an expensive calculation so that you dont have to perform the calculation next time. Heres some pseudocode explaining how this would work for a dynamically generated Web page:
缂撳瓨鐨勭洰鐨勬槸涓轰簡閬垮厤閲嶅璁$畻锛岀壒鍒槸瀵逛竴浜涙瘮杈冭楁椂闂淬佽祫婧愮殑璁$畻銆備笅闈㈢殑浼唬鐮佹紨绀轰簡濡備綍瀵瑰姩鎬侀〉闈㈢殑缁撴灉杩涜缂撳瓨銆
given a URL, try finding that page in the cache if the page is in the cache: return the cached page else: generate the page save the generated page in the cache (for next time) return the generated page
Django comes with a robust cache system that lets you save dynamic pages so they dont have to be calculated for each request. For convenience, Django offers different levels of cache granularity. You can cache the response of specific views, you can cache only the pieces that are difficult to produce, or you can cache your entire site.
涓烘锛孌jango鎻愪緵浜嗕竴涓ǔ瀹氱殑缂撳瓨绯荤粺璁╀綘缂撳瓨鍔ㄦ侀〉闈㈢殑缁撴灉锛岃繖鏍峰湪鎺ヤ笅鏉ユ湁鐩稿悓鐨勮姹傚氨鍙互鐩存帴浣跨敤缂撳瓨涓殑鏁版嵁锛岄伩鍏嶄笉蹇呰鐨勯噸澶嶈绠椼傚彟澶朌jango杩樻彁渚涗簡涓嶅悓绮掑害鏁版嵁鐨勭紦瀛橈紝渚嬪锛氫綘鍙互缂撳瓨鏁翠釜椤甸潰锛屼篃鍙互缂撳瓨鏌愪釜閮ㄥ垎锛岀敋鑷崇紦瀛樻暣涓綉绔欍
Django also works well with upstream caches, such as Squid (http://www.squid-cache.org/) and browser-based caches. These are the types of caches that you dont directly control but to which you can provide hints (via HTTP headers) about which parts of your site should be cached, and how.
Django涔熷拰”涓婃父”缂撳瓨宸ヤ綔鐨勫緢濂斤紝渚嬪Squid(http://www.squid-cache.org)鍜屽熀浜庢祻瑙堝櫒鐨勭紦瀛橈紝杩欎簺绫诲瀷鐨勭紦瀛樹綘涓嶇洿鎺ユ帶鍒讹紝浣嗘槸浣犲彲浠ユ彁渚涘叧浜庝綘鐨勭珯鐐瑰摢閮ㄥ垎搴旇琚紦瀛樺拰鎬庢牱缂撳瓨鐨勭嚎绱(閫氳繃HTTP澶撮儴)缁欏畠浠
Read on to discover how to use Djangos caching system. When your site gets Slashdotted youll be happy you understand this material.
缁х画闃呰鏉ョ爺绌跺浣曚娇鐢―jango鐨勭紦瀛樼郴缁熴傚綋浣犵殑缃戠珯鍙樻垚璞lashdot鐨勬椂鍊欙紝浣犱細寰堝緢楂樺叴鐞嗚В浜嗚繖閮ㄥ垎鏉愭枡
The cache system requires a small amount of setup. Namely, you have to tell it where your cached data should live, whether in a database, on the filesystem, or directly in memory. This is an important decision that affects your caches performance (yes, some cache types are faster than others). In-memory caching will generally be much faster than filesystem or database caching, because it lacks the overhead of hitting the filesystem or database.
缂撳瓨绯荤粺闇瑕佷竴浜涘皯閲忕殑璁惧畾宸ヤ綔锛屽嵆浣犲繀闇鍛婅瘔瀹冧綘鐨勭紦瀛樻暟鎹湪鍝噷—鍦ㄦ暟鎹簱锛屾枃浠剁郴缁熸垨鑰呯洿鎺ュ湪鍐呭瓨涓紝杩欐槸褰卞搷浣犵殑缂撳瓨鎬ц兘鐨勯噸瑕佸喅瀹氾紝鏄殑锛屼竴浜涚紦瀛樼被鍨嬭姣斿叾瀹冪殑蹇紝鍐呭瓨缂撳瓨閫氬父姣旀枃浠剁郴缁熸垨鏁版嵁搴撶紦瀛樺揩锛屽洜涓哄墠鑰呮病鏈夎闂枃浠剁郴缁熸垨鏁版嵁搴撶殑杩囧害杩炴帴
Your cache preference goes in the CACHE_BACKEND setting in your settings file. If you use caching and do not specify CACHE_BACKEND , Django will use simple:/// by default. The following sections explain all available values for CACHE_BACKEND .
浣犵殑缂撳瓨閫夋嫨鍦ㄤ綘鐨剆ettings鏂囦欢鐨 CACHE_BACKEND 璁剧疆涓紝濡傛灉浣犱娇鐢ㄧ紦瀛樹絾娌℃湁鎸囧畾 CACHE_BACKEND 锛孌jango灏嗛粯璁や娇鐢 simple:/// 锛屼笅闈㈠皢瑙i噴 CACHE_BACKEND 鐨勬墍鏈夊彲寰楀埌鐨勫
By far the fastest, most efficient type of cache available to Django, Memcached is an entirely memory-based cache framework originally developed to handle high loads at LiveJournal (http://www.livejournal.com/) and subsequently open-sourced by Danga Interactive (http://danga.com/). Its used by sites such as Slashdot and Wikipedia to reduce database access and dramatically increase site performance.
鐩墠涓烘Django鍙緱鍒扮殑鏈蹇殑鏈楂樻晥鐨勭紦瀛樼被鍨嬫槸鍩轰簬鍐呭瓨鐨勭紦瀛樻鏋禡emcached锛屽畠璧峰垵寮鍙戞潵涓篖iveJournal.com澶勭悊楂樿礋鑽峰苟闅忓悗琚獶anga Interactive(http://www.danga.com)寮婧愶紝瀹冭Slashdot鍜學ikipedia绛夌珯鐐归噰鐢ㄤ互鍑忓皯鏁版嵁搴撹闂苟鏋佸ぇ鐨勬彁鍗囦簡绔欑偣鎬ц兘
Memcached is available for free at http://danga.com/memcached/. It runs as a daemon and is allotted a specified amount of RAM. Its primary feature is to provide an interfacea super-lightning-fast interfacefor adding, retrieving, and deleting arbitrary data in the cache. All data is stored directly in memory, so theres no overhead of database or filesystem usage.
Memcached鍙互鍦╤ttp://danga.com/memcached/鍏嶈垂寰楀埌锛屽畠浣滀负鍚庡彴杩涚▼杩愯骞跺垎閰嶄竴涓寚瀹氭暟閲忕殑RAM.瀹冭兘涓轰綘鎻愪緵鍦ㄧ紦瀛樹腑*濡傞棯鐢佃埇蹇熺殑*娣诲姞锛岃幏鍙栧拰鍒犻櫎浠绘剰鏁版嵁锛屾墍鏈夌殑鏁版嵁鐩存帴瀛樺偍鍦ㄥ唴瀛樹腑锛屾墍浠ユ病鏈夋暟鎹簱鍜屾枃浠剁郴缁熶娇鐢ㄧ殑杩囧害浣跨敤
After installing Memcached itself, youll need to install the Memcached Python bindings, which are not bundled with Django directly. These bindings are in a single Python module, memcache.py , which is available at http://www.tummy.com/Community/software/python-memcached/.
鍦ㄥ畨瑁呬簡Memcached鏈韩涔嬪悗锛屼綘灏嗛渶瑕佸畨瑁匨emcached Python缁戝畾锛屽畠娌℃湁鐩存帴鍜孌jango缁戝畾锛岃繖浜涚粦瀹氬湪涓涓崟鐙殑Python妯″潡涓紝’memcache.py’锛屽彲浠ュ湪http://www.djangoproject.com/thirdparty/python-memcached寰楀埌
To use Memcached with Django, set CACHE_BACKEND to memcached://ip:port/ , where ip is the IP address of the Memcached daemon and port is the port on which Memcached is running.
璁剧疆 CACHE_BACKEND 涓 memcached://ip:port/ 鏉ヨDjango浣跨敤Memcached锛岃繖閲岀殑 ip 鏄疢emcached鍚庡彴杩涚▼鐨処P鍦板潃锛 port 鍒欐槸Memcached杩愯鎵鍦ㄧ殑绔彛
In this example, Memcached is running on localhost (127.0.0.1) port 11211:
鍦ㄨ繖涓緥瀛愪腑锛孧emcached杩愯鍦ㄦ湰鍦颁富鏈 (127.0.0.1)涓,绔彛涓11211锛
CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
One excellent feature of Memcached is its ability to share cache over multiple servers. This means you can run Memcached daemons on multiple machines, and the program will treat the group of machines as a single cache, without the need to duplicate cache values on each machine. To take advantage of this feature with Django, include all server addresses in CACHE_BACKEND , separated by semicolons.
Memcached鐨勪竴涓瀬濂界殑鐗规ф槸瀹冨湪澶氫釜鏈嶅姟鍣ㄥ垎浜紦瀛樼殑鑳藉姏锛岃繖鎰忓懗鐫浣犲彲浠ュ湪澶氬彴鏈哄櫒涓婅繍琛孧emcached杩涚▼锛岀▼搴忓皢浼氭妸杩欑粍鏈哄櫒褰撲綔涓涓*鍗曠嫭鐨*缂撳瓨锛岃屼笉闇瑕佸湪姣忓彴鏈哄櫒涓婂鍒剁紦瀛樺硷紝涓轰簡璁〥jango鍒╃敤姝ょ壒鎬э紝闇瑕佸湪CACHE_BACKEND閲屽寘鍚墍鏈夌殑鏈嶅姟鍣ㄥ湴鍧骞剁敤鍒嗗彿鍒嗛殧
In this example, the cache is shared over Memcached instances running on the IP addresses 172.19.26.240 and 172.19.26.242, both of which are on port 11211:
杩欎釜渚嬪瓙涓紝缂撳瓨鍦ㄨ繍琛屽湪172.19.26.240鍜172.19.26.242鐨処P鍦板潃鍜11211绔彛鐨凪emcached瀹炰緥闂村垎浜:
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
In the following example, the cache is shared over Memcached instances running on the IP addresses 172.19.26.240 (port 11211), 172.19.26.242 (port 11212), and 172.19.26.244 (port 11213):
杩欎釜渚嬪瓙涓紝缂撳瓨鍦ㄨ繍琛屽湪172.19.26.240(绔彛11211)锛172.19.26.242(绔彛11212)锛172.19.26.244(绔彛11213)鐨凪emcached瀹炰緥闂村垎浜:
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11212;172.19.26.244:11213/'
A final point about Memcached is that memory-based caching has one important disadvantage. Because the cached data is stored only in memory, the data will be lost if your server crashes. Clearly, memory isnt intended for permanent data storage, so dont rely on memory-based caching as your only data storage. Without a doubt, none of the Django caching back-ends should be used for permanent storagetheyre all intended to be solutions for caching, not storagebut we point this out here because memory-based caching is particularly temporary.
鏈鍚庡叧浜嶮emcached鐨勬槸鍩轰簬鍐呭瓨鐨勭紦瀛樻湁涓涓噸澶х殑缂虹偣锛屽洜涓虹紦瀛樻暟鎹彧瀛樺偍鍦ㄥ唴瀛樹腑锛屽垯濡傛灉鏈嶅姟鍣ㄦ鏈虹殑璇濇暟鎹細涓㈠け锛屾樉鐒跺唴瀛樹笉鏄负鎸佷箙鏁版嵁瀛樺偍鍑嗗鐨勶紝Django娌℃湁涓涓紦瀛樺悗绔槸鐢ㄦ潵鍋氭寔涔呭瓨鍌ㄧ殑锛屽畠浠兘鏄紦瀛樻柟妗堬紝鑰屼笉鏄瓨鍌.浣嗘槸鎴戜滑鍦ㄨ繖閲屾寚鍑烘槸鍥犱负鍩轰簬鍐呭瓨鐨勭紦瀛樼壒鍒殑鐭殏 .
To use a database table as your cache back-end, create a cache table in your database and point Djangos cache system at that table.
涓轰簡灏嗘暟鎹簱琛ㄤ綔涓虹紦瀛樺悗绔紝闇瑕佸湪鏁版嵁搴撲腑鍒涘缓涓涓紦瀛樿〃骞跺皢Django鐨勭紦瀛樼郴缁熸寚鍚戣琛
First, create a cache table by running this command:
棣栧厛,浣跨敤濡備笅璇彞鍒涘缓涓涓紦瀛樼敤鏁版嵁琛:
python manage.py createcachetable [cache_table_name]
where [cache_table_name] is the name of the database table to create. This name can be whatever you want, as long as its a valid table name thats not already being used in your database. This command creates a single table in your database that is in the proper format Djangos database-cache system expects.
杩欓噷鐨刐cache_table_name]鏄鍒涘缓鐨勬暟鎹簱琛ㄥ悕锛屽悕瀛楀彲浠ユ槸浠讳綍浣犳兂瑕佺殑锛屽彧瑕佸畠鏄悎娉曠殑鍦ㄤ綘鐨勬暟鎹簱涓病鏈夎浣跨敤锛岃繖涓懡浠ゅ湪浣犵殑鏁版嵁搴撳垱寤轰竴涓伒寰狣jango鐨勬暟鎹簱缂撳瓨绯荤粺鏈熸湜褰㈠紡鐨勫崟鐙殑琛.
Once youve created that database table, set your CACHE_BACKEND setting to "db://tablename" , where tablename is the name of the database table. In this example, the cache tables name is my_cache_table :
涓鏃︿綘鍒涘缓浜嗘暟鎹簱琛紝璁剧疆浣犵殑CACHE_BACKEND璁剧疆涓”db://tablename”锛岃繖閲岀殑tablename鏄暟鎹簱琛ㄧ殑鍚嶅瓧锛屽湪杩欎釜渚嬪瓙涓紝缂撳瓨琛ㄥ悕涓簃y_cache_table:
CACHE_BACKEND = 'db://my_cache_table'
The database caching back-end uses the same database as specified in your settings file. You cant use a different database back-end for your cache table.
鏁版嵁搴撶紦瀛樺悗绔娇鐢ㄤ綘鐨剆ettings鏂囦欢鎸囧畾鐨勫悓涓鏁版嵁搴擄紝浣犱笉鑳戒负浣犵殑缂撳瓨琛ㄤ娇鐢ㄤ笉鍚岀殑鏁版嵁搴撳悗绔.
To store cached items on a filesystem, use the "file://" cache type for CACHE_BACKEND , specifying the directory on your filesystem that should store the cached data.
浣跨敤”file://“缂撳瓨绫诲瀷浣滀负CACHE_BACKEND骞舵寚瀹氬瓨鍌ㄧ紦瀛樻暟鎹殑鏂囦欢绯荤粺鐩綍鏉ュ湪鏂囦欢绯荤粺瀛樺偍缂撳瓨鏁版嵁.
For example, to store cached data in /var/tmp/django_cache , use this setting:
渚嬪锛屼娇鐢ㄤ笅闈㈢殑璁剧疆鏉ュ湪/var/tmp/django_cache瀛樺偍缂撳瓨鏁版嵁:
CACHE_BACKEND = 'file:///var/tmp/django_cache'
Note that there are three forward slashes toward the beginning of the preceding example. The first two are for file:// , and the third is the first character of the directory path, /var/tmp/django_cache . If youre on Windows, put the drive letter after the file:// , like so:: file://c:/foo/bar .
娉ㄦ剰渚嬪瓙涓紑澶存湁涓変釜鍓嶆枩绾匡紝鍓嶄袱涓槸file://锛岀涓変釜鏄洰褰曡矾寰勭殑绗竴涓瓧绗︼紝/var/tmp/django_cache锛屽鏋滀綘浣跨敤Windows绯荤粺锛屾妸鐩樼瀛楁瘝鏀惧湪file://鍚庨潰锛屽儚杩欐牱:’file://c:/foo/bar‘.
The directory path should be absolute that is, it should start at the root of your filesystem. It doesnt matter whether you put a slash at the end of the setting.
鐩綍璺緞搴旇鏄*缁濆*璺緞锛屽嵆搴旇浠ヤ綘鐨勬枃浠剁郴缁熺殑鏍瑰紑濮嬶紝浣犲湪璁剧疆鐨勭粨灏炬斁缃枩绾夸笌鍚︽棤鍏崇揣瑕.
Make sure the directory pointed to by this setting exists and is readable and writable by the system user under which your Web server runs. Continuing the preceding example, if your server runs as the user apache , make sure the directory /var/tmp/django_cache exists and is readable and writable by the user apache .
纭璇ヨ缃寚鍚戠殑鐩綍瀛樺湪骞朵笖浣犵殑Web鏈嶅姟鍣ㄨ繍琛岀殑绯荤粺鐨勭敤鎴峰彲浠ヨ鍐欒鐩綍锛岀户缁笂闈㈢殑渚嬪瓙锛屽鏋滀綘鐨勬湇鍔″櫒浠ョ敤鎴穉pache杩愯锛岀‘璁/var/tmp/django_cache瀛樺湪骞朵笖鐢ㄦ埛apache鍙互璇诲啓/var/tmp/django_cache鐩綍
Each cache value will be stored as a separate file whose contents are the cache data saved in a serialized (pickled) format, using Pythons pickle module. Each files name is the cache key, escaped for safe filesystem use.
姣忎釜缂撳瓨鍊煎皢琚瓨鍌ㄤ负鍗曠嫭鐨勬枃浠讹紝鍏跺唴瀹规槸Python鐨刾ickle妯″潡浠ュ簭鍒楀寲(“pickled”)褰㈠紡淇濆瓨鐨勭紦瀛樻暟鎹紝姣忎釜鏂囦欢鐨 鏂囦欢鍚嶆槸缂撳瓨閿紝浠ヨ閬垮紑瀹夊叏鏂囦欢绯荤粺鐨勪娇鐢
If you want the speed advantages of in-memory caching but dont have the capability of running Memcached, consider the local-memory cache back-end. This cache is per-process and thread-safe, but it isnt as efficient as Memcached due to its simplistic locking and memory allocation strategies.
濡傛灉浣犳兂瑕佸唴瀛樼紦瀛樼殑閫熷害浼樺娍浣嗘病鏈夎兘鍔涜繍琛孧emcached锛屽彲浠ヨ冭檻浣跨敤鏈湴瀛樺偍鍣ㄧ紦瀛樺悗绔紝璇ョ紦瀛樻槸澶氱嚎绋嬪拰绾跨▼瀹夊叏 鐨勶紝浣嗘槸鐢变簬鍏剁畝鍗曠殑閿佸拰鍐呭瓨鍒嗛厤绛栫暐瀹冩病鏈塎emcached楂樻晥
To use it, set CACHE_BACKEND to 'locmem:///' , for example:
璁剧疆 CACHE_BACKEND 涓 locmem:/// 鏉ヤ娇鐢ㄥ畠锛屼緥濡:
CACHE_BACKEND = 'locmem:///'
A simple, single-process memory cache is available as 'simple:///' , for example:
鍙互閫氳繃閰嶇疆 'simple:///' 鏉ヤ娇鐢ㄤ竴涓畝鍗曠殑鍗曡繘绋嬪唴瀛樼紦瀛橈紝渚嬪锛
CACHE_BACKEND = 'simple:///'
This cache merely saves cached data in process, which means it should be used only in development or testing environments.
杩欎釜缂撳瓨浠呬粎鏄皢鏁版嵁淇濆瓨鍦ㄨ繘绋嬪唴锛屽洜姝ゅ畠搴旇鍙湪寮鍙戠幆澧冩垨娴嬭瘯鐜涓娇鐢.
Finally, Django comes with a dummy cache that doesnt actually cache; it just implements the cache interface without doing anything.
鏈鍚庯紝Django鎻愪緵涓涓亣缂撳瓨鐨勮缃細瀹冧粎浠呭疄鐜颁簡缂撳瓨鐨勬帴鍙h屼笉鍋氫换浣曞疄闄呯殑浜嬫儏
This is useful if you have a production site that uses heavy-duty caching in various places and a development/test environment on which you dont want to cache. In that case, set CACHE_BACKEND to 'dummy:///' in the settings file for your development environment, for example:
杩欐槸涓湁鐢ㄧ殑鐗规э紝濡傛灉浣犵殑绾夸笂绔欑偣浣跨敤浜嗗緢澶氭瘮杈冮噸鐨勭紦瀛橈紝鑰屽湪寮鍙戠幆澧冧腑鍗翠笉鎯充娇鐢ㄧ紦瀛橈紝閭d箞浣犲彧瑕佷慨鏀归厤缃枃浠讹紝灏 CACHE_BACKEND 璁剧疆涓 'dummy:///' 灏卞彲浠ヤ簡锛屼緥濡傦細
CACHE_BACKEND = 'dummy:///'
As a result, your development environment wont use caching, but your production environment still will.
杩欐牱鐨勭粨鏋滃氨鏄綘鐨勫紑鍙戠幆澧冩病鏈変娇鐢ㄧ紦瀛橈紝鑰岀嚎涓婄幆澧冧緷鐒跺湪浣跨敤缂撳瓨.
Each cache back-end may take arguments. Theyre given in query-string style on the CACHE_BACKEND setting. Valid arguments are as follows:
姣忎釜缂撳瓨鍚庣閮藉彲鑳戒娇鐢ㄥ弬鏁帮紝瀹冧滑鍦–ACHE_BACKEND璁剧疆涓互鏌ヨ瀛楃涓插舰寮忕粰鍑猴紝鍚堟硶鐨勫弬鏁颁负:
timeout : The default timeout, in seconds, to use for the cache. This argument defaults to 300 seconds (5 minutes).
timeout:鐢ㄤ簬缂撳瓨鐨勮繃鏈熸椂闂达紝浠ョ涓哄崟浣嶃傝繖涓弬鏁伴粯璁よ璁剧疆涓300绉掞紙浜斿垎閽燂級
max_entries : For the simple, local-memory, and database back-ends, the maximum number of entries allowed in the cache before old values are deleted. This argument defaults to 300.
max_entries : 瀵逛簬simple, local-memory涓巇atabase绫诲瀷鐨勭紦瀛,杩欎釜鍙傛暟鏄寚瀹氱紦瀛樹腑瀛樻斁鐨勬渶澶ф潯鐩暟锛屽ぇ浜庤繖涓暟鏃讹紝鏃х殑鏉$洰灏嗕細琚垹闄ゃ傝繖涓弬鏁伴粯璁ゆ槸300.
cull_frequency : The ratio of entries that are culled when max_entries is reached. The actual ratio is 1/cull_frequency , so set cull_frequency=2 to cull half of the entries when max_entries is reached.
cull_frequency :褰撹揪鍒 max_entries 鐨勬椂鍊,琚帴鍙楃殑璁块棶鐨勬瘮鐜囥傚疄闄呯殑姣旂巼鏄 1/cull_frequency ,鎵浠ヨ缃甤ull_frequency=2灏辨槸鍦ㄨ揪鍒 max_entries 鐨勬椂鍊欏幓闄や竴鍗婃暟閲忕殑缂撳瓨
A value of 0 for cull_frequency means that the entire cache will be dumped when max_entries is reached. This makes culling much faster at the expense of more cache misses. This argument defaults to 3.
鎶 cull_frequency 鐨勫艰缃负 0 鎰忓懗鐫褰撹揪鍒 max_entries 鏃,缂撳瓨灏嗚娓呯┖銆傝繖灏嗕互寰堝缂撳瓨涓㈠け涓轰唬浠,澶уぇ鎻愰珮鎺ュ彈璁块棶鐨勯熷害銆傝繖涓奸粯璁ゆ槸3
In this example, timeout is set to 60 :
鍦ㄨ繖涓緥瀛愪腑锛 timeout 琚鎴 60
CACHE_BACKEND = "locmem:///?timeout=60"
In this example, timeout is 30 and max_entries is 400 :
鑰屽湪杩欎釜渚嬪瓙涓紝 timeout 璁句负 30 鑰 max_entries 涓 400 :
CACHE_BACKEND = "locmem:///?timeout=30&max_entries=400"
Invalid arguments are silently ignored, as are invalid values of known arguments.
鍏朵腑锛岄潪娉曠殑鍙傛暟涓庨潪娉曠殑鍙傛暟鍊奸兘灏嗚蹇界暐銆
Once youve specified CACHE_BACKEND , the simplest way to use caching is to cache your entire site. This means each page that doesnt have GET or POST parameters will be cached for a specified amount of time the first time its requested.
涓鏃︿綘鎸囧畾浜”CACHE_BACKEND”锛屼娇鐢ㄧ紦瀛樼殑鏈绠鍗曠殑鏂规硶灏辨槸缂撳瓨浣犵殑鏁翠釜缃戠珯銆傝繖鎰忓懗鐫鎵鏈変笉鍖呭惈GET鎴朠OST鍙傛暟鐨勯〉闈㈠湪绗竴娆¤璇锋眰涔嬪悗灏嗚缂撳瓨鎸囧畾濂界殑涓娈垫椂闂达紙灏辨槸璁剧疆鐨則imeout鍙傛暟锛夈
To activate the per-site cache, just add 'django.middleware.cache.CacheMiddleware' to your MIDDLEWARE_CLASSES setting, as in this example:
瑕佹縺娲绘瘡涓珯鐐圭殑cache锛屽彧瑕佸皢``’django.middleware.cache.CacheMiddleware’`` 娣诲姞鍒 MIDDLEWARE_CLASSES 鐨勮缃噷锛屽氨鍍忎笅闈㈣繖鏍凤細
MIDDLEWARE_CLASSES = ( 'django.middleware.cache.CacheMiddleware', 'django.middleware.common.CommonMiddleware', )
Note
娉ㄦ剰
The order of MIDDLEWARE_CLASSES matters. See the section Order of MIDDLEWARE_CLASSES later in this chapter.
鍏充簬 MIDDLEWARE_CLASSES 椤哄簭鐨勪竴浜涗簨鎯呫傝鐪嬫湰绔犺妭鍚庨潰鐨凪IDDLEWARE_CLASSES椤哄簭閮ㄥ垎銆
Then, add the following required settings to your Django settings file:
鐒跺悗锛屽湪浣犵殑Django settings鏂囦欢閲屽姞鍏ヤ笅闈㈡墍闇鐨勮缃細
CACHE_MIDDLEWARE_SECONDS : The number of seconds each page should be cached.
CACHE_MIDDLEWARE_SECONDS :姣忎釜椤甸潰搴旇琚紦瀛樼殑绉掓暟
CACHE_MIDDLEWARE_KEY_PREFIX : If the cache is shared across multiple sites using the same Django installation, set this to the name of the site, or some other string that is unique to this Django instance, to prevent key collisions. Use an empty string if you dont care.
CACHE_MIDDLEWARE_KEY_PREFIX 锛氬鏋滅紦瀛樿澶氫釜浣跨敤鐩稿悓Django瀹夎鐨勭綉绔欐墍鍏变韩锛岄偅涔堟妸杩欎釜鍊艰鎴愬綋鍓嶇綉绔欏悕锛屾垨鍏朵粬鑳戒唬琛ㄨ繖涓狣jango瀹炰緥鐨勫敮涓瀛楃涓诧紝浠ラ伩鍏峩ey鍙戠敓鍐茬獊銆傚鏋滀綘涓嶅湪鎰忕殑璇濆彲浠ヨ鎴愮┖瀛楃涓层
The cache middleware caches every page that doesnt have GET or POST parameters. That is, if a user requests a page and passes GET parameters in a query string, or passes POST parameters, the middleware will not attempt to retrieve a cached version of the page. If you intend to use the per-site cache, keep this in mind as you design your application; dont use URLs with query strings, for example, unless it is acceptable for your application not to cache those pages.
缂撳瓨涓棿浠剁紦瀛樻瘡涓病鏈塆ET鎴栬匬OST鍙傛暟鐨勯〉闈紝鍗冲鏋滅敤鎴疯姹傞〉闈㈠苟鍦ㄦ煡璇㈠瓧绗︿覆閲屼紶閫扜ET鍙傛暟鎴栬匬OST鍙傛暟锛屼腑闂翠欢灏嗕笉浼氬皾璇曞緱鍒扮紦瀛樼増鏈殑椤甸潰锛屽鏋滀綘鎵撶畻浣跨敤鏁寸珯缂撳瓨锛岃璁′綘鐨勭▼搴忔椂鐗㈣杩欑偣锛屼緥濡傦紝涓嶈浣跨敤鎷ユ湁鏌ヨ瀛楃涓茬殑URLs锛岄櫎闈為偅浜涢〉闈㈠彲浠ヤ笉缂撳瓨
The cache middleware supports another setting, CACHE_MIDDLEWARE_ANONYMOUS_ONLY . If youve defined this setting, and its set to True , then the cache middleware will only cache anonymous requests (i.e., those requests made by a non-logged-in user). This is a simple and effective way of disabling caching for any user-specific pages, such as Djangos admin interface. Note that if you use CACHE_MIDDLEWARE_ANONYMOUS_ONLY , you should make sure youve activated AuthenticationMiddleware and that AuthenticationMiddleware appears before CacheMiddleware in your MIDDLEWARE_CLASSES .
缂撳瓨涓棿浠讹紙 cache middleware锛夋敮鎸佸彟澶栦竴绉嶈缃夐」, CACHE_MIDDLEWARE_ANONYMOUS_ONLY 銆傚鏋滀綘鎶婂畠璁剧疆涓衡淭rue鈥,閭d箞缂撳瓨涓棿浠跺氨鍙細瀵瑰尶鍚嶈姹傝繘琛岀紦瀛橈紝 鍖垮悕璇锋眰鏄寚閭d簺 娌℃湁鐧诲綍鐨勭敤鎴峰彂璧风殑璇锋眰銆傚鏋滄兂鍙栨秷鐢ㄦ埛鐩稿叧椤甸潰锛坲ser-specific pages锛夌殑缂撳瓨锛屼緥濡侱jangos 鐨勭鐞嗙晫闈紝杩欐槸涓绉嶆棦绠鍗曞張鏈夋晥鐨勬柟娉曘傚彟澶栵紝濡傛灉浣犺浣跨敤 CACHE_MIDDLEWARE_ANONYMOUS_ONLY 閫夐」锛屼綘蹇呴』鍏堟縺娲 AuthenticationMiddleware 鎵嶈锛屼篃灏辨槸鍦ㄤ綘鐨勯厤缃枃浠 MIDDLEWARE_CLASSES 鐨勫湴鏂癸紝 AuthenticationMiddleware 蹇呴』鍑虹幇鍦 CacheMiddleware 鍓嶉潰銆
Finally, note that CacheMiddleware automatically sets a few headers in each HttpResponse :
鏈鍚庯紝鍐嶆彁閱掍竴涓嬶細 CacheMiddleware 鍦ㄦ瘡涓 HttpResponse 涓兘浼氳嚜鍔ㄨ缃竴浜涘ご閮ㄤ俊鎭紙headers锛
It sets the Last-Modified header to the current date/time when a fresh (uncached) version of the page is requested.
褰撲竴涓柊(娌$紦瀛樼殑)鐗堟湰鐨勯〉闈㈣璇锋眰鏃惰缃甃ast-Modified澶撮儴涓哄綋鍓嶆棩鏈/鏃堕棿
It sets the Expires header to the current date/time plus the defined CACHE_MIDDLEWARE_SECONDS .
璁剧疆Expires澶撮儴涓哄綋鍓嶆棩鏈/鏃堕棿鍔犱笂瀹氫箟鐨凜ACHE_MIDDLEWARE_SECONDS
It sets the Cache-Control header to give a maximum age for the page, again from the CACHE_MIDDLEWARE_SECONDS setting.
璁剧疆Cache-Control澶撮儴鏉ョ粰椤甸潰涓涓渶澶х殑鏃堕棿—鍐嶄竴娆★紝鏍规嵁CACHE_MIDDLEWARE_SECONDS璁剧疆
A more granular way to use the caching framework is by caching the output of individual views. This has the same effects as the per-site cache (including the omission of caching on requests with GET and POST parameters). It applies to whichever views you specify, rather than the whole site.
鏇村姞棰楃矑绾х殑缂撳瓨妗嗘灦浣跨敤鏂规硶鏄鍗曚釜瑙嗗浘鐨勮緭鍑鸿繘琛岀紦瀛樸傝繖鍜屾暣绔欑骇缂撳瓨鏈変竴鏍风殑鏁堟灉锛堝寘鎷拷鐣ュ鏈 GET 鍜 POST 鍙傛暟鐨勮姹傜殑缂撳瓨锛夈傚畠搴旂敤浜庝綘鎵鎸囧畾鐨勮鍥撅紝鑰屼笉鏄暣涓珯鐐广
Do this by using a decorator , which is a wrapper around your view function that alters its behavior to use caching. The per-view cache decorator is called cache_page and is located in the django.views.decorators.cache module, for example:
瀹屾垚杩欓」宸ヤ綔鐨勬柟寮忔槸浣跨敤 淇グ鍣 锛屽叾浣滅敤鏄寘瑁硅鍥惧嚱鏁帮紝灏嗗叾琛屼负杞崲涓轰娇鐢ㄧ紦瀛樸傝鍥剧紦瀛樹慨楗板櫒绉颁负 cache_page 锛屼綅浜 django.views.decorators.cache 妯″潡涓紝渚嬪锛
from django.views.decorators.cache import cache_page def my_view(request, param): # ... my_view = cache_page(my_view, 60 * 15)
Alternatively, if youre using Python 2.4 or greater, you can use decorator syntax. This example is equivalent to the preceding one:
濡傛灉浣跨敤 Python 2.4 鎴栨洿楂樼増鏈, 浣犱篃鍙互浣跨敤 decorator 璇硶銆傝繖涓緥瀛愬拰鍓嶉潰鐨勯偅涓槸绛夊悓鐨:
from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request, param): # ...
cache_page takes a single argument: the cache timeout, in seconds. In the preceding example, the result of the my_view() view will be cached for 15 minutes. (Note that weve written it as 60 * 15 for the purpose of readability. 60 * 15 will be evaluated to 900 that is, 15 minutes multiplied by 60 seconds per minute.)
cache_page 鍙帴鍙椾竴涓弬鏁帮細浠ョ璁$殑缂撳瓨瓒呮椂銆傚湪鍓嶄緥涓紝 “my_view()” 瑙嗗浘鐨勭粨鏋滃皢琚紦瀛 15 鍒嗛挓銆傦紙娉ㄦ剰锛氫负浜嗘彁楂樺彲璇绘э紝璇ュ弬鏁拌涔﹀啓涓 60 * 15 銆 60 * 15 灏嗚璁$畻涓 900 锛屼篃灏辨槸璇15 鍒嗛挓涔樹互姣忓垎閽 60 绉掋傦級
The per-view cache, like the per-site cache, is keyed off of the URL. If multiple URLs point at the same view, each URL will be cached separately. Continuing the my_view example, if your URLconf looks like this:
鍜岀珯鐐圭紦瀛樹竴鏍凤紝瑙嗗浘缂撳瓨涓 URL 鏃犲叧銆傚鏋滃涓 URL 鎸囧悜鍚屼竴瑙嗗浘锛屾瘡涓鍥惧皢浼氬垎鍒紦瀛樸傜户缁 my_view 鑼冧緥锛屽鏋 URLconf 濡備笅鎵绀猴細
urlpatterns = ('', (r'^foo/(\d{1,2})/$', my_view), )
then requests to /foo/1/ and /foo/23/ will be cached separately, as you may expect. But once a particular URL (e.g., /foo/23/ ) has been requested, subsequent requests to that URL will use the cache.
閭d箞姝e浣犳墍鏈熷緟鐨勯偅鏍凤紝鍙戦佸埌 /foo/1/ 鍜 /foo/23/ 鐨勮姹傚皢浼氬垎鍒紦瀛樸備絾涓鏃﹀彂鍑轰簡鐗瑰畾鐨勮姹傦紙濡傦細 /foo/23/ 锛夛紝涔嬪悗鍐嶅害鍙戝嚭鐨勬寚鍚戣 URL 鐨勮姹傚皢浣跨敤缂撳瓨銆
The examples in the previous section have hard-coded the fact that the view is cached, because cache_page alters the my_view function in place. This approach couples your view to the cache system, which is not ideal for several reasons. For instance, you might want to reuse the view functions on another, cacheless site, or you might want to distribute the views to people who might want to use them without being cached. The solution to these problems is to specify the per-view cache in the URLconf rather than next to the view functions themselves.
鍓嶄竴鑺備腑鐨勮寖渚嬪皢瑙嗗浘纭紪鐮佷负浣跨敤缂撳瓨锛屽洜涓 cache_page 鍦ㄩ傚綋鐨勪綅缃 my_view 鍑芥暟杩涜浜嗚浆鎹€傝鏂规硶灏嗚鍥句笌缂撳瓨绯荤粺杩涜浜嗚﹀悎锛屼粠鍑犱釜鏂归潰鏉ヨ骞朵笉鐞嗘兂銆備緥濡傦紝浣犲彲鑳芥兂鍦ㄦ煇涓棤缂撳瓨鐨勭珯鐐逛腑閲嶇敤璇ヨ鍥惧嚱鏁帮紝鎴栬呬綘鍙兘鎯冲皢璇ヨ鍥惧彂甯冪粰閭d簺涓嶆兂閫氳繃缂撳瓨浣跨敤瀹冧滑鐨勪汉銆傝В鍐宠繖浜涢棶棰樼殑鏂规硶鏄湪 URLconf 涓寚瀹氳鍥剧紦瀛橈紝鑰屼笉鏄揣鎸ㄧ潃杩欎簺瑙嗗浘鍑芥暟鏈韩鏉ユ寚瀹氥
Doing so is easy: simply wrap the view function with cache_page when you refer to it in the URLconf. Heres the old URLconf from earlier:
瀹屾垚杩欓」宸ヤ綔闈炲父绠鍗曪細鍦 URLconf 涓敤鍒拌繖浜涜鍥惧嚱鏁扮殑鏃跺欑畝鍗曞湴鍖呰9涓涓 cache_page 銆備互涓嬫槸鍒氭墠鐢ㄥ埌杩囩殑 URLconf :
urlpatterns = ('', (r'^foo/(\d{1,2})/$', my_view), )
Heres the same thing, with my_view wrapped in cache_page :
浠ヤ笅鏄悓涓涓 URLconf 锛屼笉杩囩敤 cache_page 鍖呰9浜 my_view 锛
from django.views.decorators.cache import cache_page urlpatterns = ('', (r'^foo/(\d{1,2})/$', cache_page(my_view, 60 * 15)), )
If you take this approach, dont forget to import cache_page within your URLconf.
濡傛灉閲囧彇杩欑鏂规硶, 涓嶈蹇樿鍦 URLconf 涓鍏 cache_page .
Sometimes, caching an entire rendered page doesnt gain you very much and is, in fact, inconvenient overkill.
鏈変簺鏃跺欙紝瀵规暣涓粡瑙f瀽鐨勯〉闈㈣繘琛岀紦瀛樺苟涓嶄細缁欎綘甯︽潵澶锛屼簨瀹炰笂鍙兘浼氳繃鐘逛笉鍙娿
Perhaps, for instance, your site includes a view whose results depend on several expensive queries, the results of which change at different intervals. In this case, it would not be ideal to use the full-page caching that the per-site or per-view cache strategies offer, because you wouldnt want to cache the entire result (since some of the data changes often), but youd still want to cache the results that rarely change.
姣斿璇达紝涔熻浣犵殑绔欑偣鎵鍖呭惈鐨勪竴涓鍥句緷璧栧嚑涓垂鏃剁殑鏌ヨ锛屾瘡闅斾竴娈垫椂闂寸粨鏋滃氨浼氬彂鐢熷彉鍖栥傚湪杩欑鎯呭喌涓嬶紝浣跨敤绔欑偣绾х紦瀛樻垨鑰呰鍥剧骇缂撳瓨绛栫暐鎵鎻愪緵鐨勬暣椤电紦瀛樺苟涓嶆槸鏈鐞嗘兂鐨勶紝鍥犱负浣犲彲鑳戒笉浼氭兂瀵规暣涓粨鏋滆繘琛岀紦瀛橈紙鍥犱负涓浜涙暟鎹粡甯稿彉鍖栵級锛屼絾浣犱粛鐒朵細鎯冲寰堝皯鍙樺寲鐨勯儴鍒嗚繘琛岀紦瀛樸
For cases like this, Django exposes a simple, low-level cache API, which lives in the module django.core.cache . You can use the low-level cache API to store objects in the cache with any level of granularity you like. You can cache any Python object that can be pickled safely: strings, dictionaries, lists of model objects, and so forth. (Most common Python objects can be pickled; refer to the Python documentation for more information about pickling.)
鍦ㄥ儚杩欐牱鐨勬儏褰笅锛 Django 灞曠ず浜嗕竴绉嶄綅浜 django.core.cache 妯″潡涓殑绠鍗曘佷綆灞傛鐨勭紦瀛 API 銆備綘鍙互浣跨敤杩欑浣庡眰娆$殑缂撳瓨 API 鍦ㄧ紦瀛樹腑浠ヤ换浣曠骇鍒矑搴﹁繘琛屽璞″偍瀛樸備綘鍙互瀵规墍鏈夎兘澶熷畨鍏ㄨ繘琛 pickle 澶勭悊鐨 Python 瀵硅薄杩涜缂撳瓨锛氬瓧绗︿覆銆佸瓧鍏稿拰妯″瀷瀵硅薄鍒楄〃绛夌瓑锛涙煡闃 Python 鏂囨。鍙互浜嗚В鍒版洿澶氬叧浜 pickling 鐨勪俊鎭傦級
Heres how to import the API:
涓嬮潰鏄浣曞鍏ヨ繖涓 API :
>>> from django.core.cache import cache
The basic interface is set(key, value, timeout_seconds) and get(key) :
鍩烘湰鐨勬帴鍙f槸 set(key, value, timeout_seconds) 鍜 get(key) :
>>> cache.set('my_key', 'hello, world!', 30) >>> cache.get('my_key') 'hello, world!'
The timeout_seconds argument is optional and defaults to the timeout argument in the CACHE_BACKEND setting explained earlier.
timeout_seconds 鍙傛暟鏄彲閫夌殑, 骞朵笖榛樿涓哄墠闈㈣杩囩殑 CACHE_BACKEND 璁剧疆涓殑 timeout 鍙傛暟.
If the object doesnt exist in the cache, or the cache back-end is unreachable, cache.get() returns None :
濡傛灉瀵硅薄鍦ㄧ紦瀛樹腑涓嶅瓨鍦, 鎴栬呯紦瀛樺悗绔槸涓嶅彲杈剧殑, cache.get() 杩斿洖 None :
# Wait 30 seconds for 'my_key' to expire... >>> cache.get('my_key') None >>> cache.get('some_unset_key') None
We advise against storing the literal value None in the cache, because you wont be able to distinguish between your stored None value and a cache miss signified by a return value of None .
鎴戜滑涓嶅缓璁湪缂撳瓨涓繚瀛 None 甯搁噺锛屽洜涓轰綘灏嗘棤娉曞尯鍒嗘墍淇濆瓨鐨 None 鍙橀噺鍙婄敱杩斿洖鍊 None 鎵鏍囪瘑鐨勭紦瀛樻湭涓
cache.get() can take a default argument. This specifies which value to return if the object doesnt exist in the cache:
cache.get() 鎺ュ彈涓涓 缂虹渷 鍙傛暟銆傚叾鎸囧畾浜嗗綋缂撳瓨涓笉瀛樺湪璇ュ璞℃椂鎵杩斿洖鐨勫硷細
>>> cache.get('my_key', 'has expired') 'has expired'
To retrieve multiple cache values in a single shot, use cache.get_many() . If possible for the given cache back-end, get_many() will hit the cache only once, as opposed to hitting it once per cache key. get_many() returns a dictionary with all of the keys you asked for that exist in the cache and havent expired:
瑕佹兂涓娆¤幏鍙栧涓紦瀛樺硷紝鍙互浣跨敤 cache.get_many() 銆傚鏋滃彲鑳界殑璇濓紝瀵逛簬缁欏畾鐨勭紦瀛樺悗绔紝 get_many() 灏嗗彧璁块棶缂撳瓨涓娆★紝鑰屼笉鏄姣忎釜缂撳瓨閿奸兘杩涜涓娆¤闂 get_many() 鎵杩斿洖鐨勫瓧鍏稿寘鎷簡浣犳墍璇锋眰鐨勫瓨鍦ㄤ簬缂撳瓨涓笖鏈秴鏃剁殑鎵鏈夐敭鍊笺
>>> cache.set('a', 1) >>> cache.set('b', 2) >>> cache.set('c', 3) >>> cache.get_many(['a', 'b', 'c']) {'a': 1, 'b': 2, 'c': 3}
If a cache key doesnt exist or is expired, it wont be included in the dictionary. The following is a continuation of the example:
濡傛灉鏌愪釜缂撳瓨鍏抽敭瀛椾笉瀛樺湪鎴栬呭凡瓒呮椂, 瀹冨皢涓嶄細琚寘鍚湪瀛楀吀涓 涓嬮潰鏄寖渚嬬殑寤剁画:
>>> cache.get_many(['a', 'b', 'c', 'd']) {'a': 1, 'b': 2, 'c': 3}
Finally, you can delete keys explicitly with cache.delete() . This is an easy way of clearing the cache for a particular object:
鏈鍚,浣犲彲浠ョ敤 cache.delete() 鏄惧紡鍦板垹闄ゅ叧閿瓧銆傝繖鏄湪缂撳瓨涓竻闄ょ壒瀹氬璞$殑绠鍗曢斿緞銆
>>> cache.delete('a')
cache.delete() has no return value, and it works the same way whether or not a value with the given cache key exists.
cache.delete() 娌℃湁杩斿洖鍊, 涓嶇缁欏畾鐨勭紦瀛樺叧閿瓧瀵瑰簲鐨勫煎瓨鍦ㄤ笌鍚, 瀹冮兘灏嗕互鍚屾牱鏂瑰紡宸ヤ綔銆
So far, this chapter has focused on caching your own data. But another type of caching is relevant to Web development, too: caching performed by upstream caches. These are systems that cache pages for users even before the request reaches your Web site.
鐩墠涓烘锛屾湰绔犵殑鐒︾偣涓鐩存槸瀵逛綘 鑷繁鐨 鏁版嵁杩涜缂撳瓨銆備絾杩樻湁涓绉嶄笌 Web 寮鍙戠浉鍏崇殑缂撳瓨锛氱敱 涓婃父 楂橀熺紦瀛樻墽琛岀殑缂撳啿銆傛湁涓浜涚郴缁熺敋鑷冲湪璇锋眰鍒拌揪绔欑偣涔嬪墠灏变负鐢ㄦ埛杩涜椤甸潰缂撳瓨銆
Here are a few examples of upstream caches:
涓嬮潰鏄笂娓哥紦瀛樼殑鍑犱釜渚嬪瓙锛
Your ISP may cache certain pages, so if you requested a page from http://example.com/, your ISP would send you the page without having to access example.com directly. The maintainers of example.com have no knowledge of this caching; the ISP sits between example.com and your Web browser, handling all of the caching transparently.
浣犵殑 ISP (浜掕仈缃戞湇鍔″晢)鍙兘浼氬鐗瑰畾鐨勯〉闈㈣繘琛岀紦瀛橈紝鍥犳濡傛灉浣犲悜 http://example.com/ 璇锋眰涓涓〉闈紝浣犵殑 ISP 鍙兘鏃犻渶鐩存帴璁块棶 example.com 灏辫兘灏嗛〉闈㈠彂閫佺粰浣犮傝 example.com 鐨勭淮鎶よ呬滑鍗存棤浠庡緱鐭ヨ繖绉嶇紦瀛橈紝ISP 浣嶄簬 example.com 鍜屼綘鐨勭綉椤垫祻瑙堝櫒涔嬮棿锛岄忔槑鍦板鐞嗘墍鏈夌殑缂撳瓨銆
Your Django Web site may sit behind a proxy cache , such as Squid Web Proxy Cache (http://www.squid-cache.org/), that caches pages for performance. In this case, each request first would be handled by the proxy, and it would be passed to your application only if needed.
浣犵殑 Django 缃戠珯鍙兘浣嶄簬鏌愪釜 浠g悊缂撳瓨 涔嬪悗锛屼緥濡 Squid 缃戦〉浠g悊缂撳瓨 (http://www.squid-cache.org/)锛岃缂撳瓨涓烘彁楂樻ц兘鑰屽椤甸潰杩涜缂撳瓨銆傚湪姝ゆ儏鍐典笅 锛屾瘡涓姹傚皢棣栧厛鐢变唬鐞嗘湇鍔″櫒杩涜澶勭悊锛岀劧鍚庝粎鍦ㄩ渶瑕佺殑鎯呭喌涓嬫墠琚紶閫掕嚦浣犵殑搴旂敤绋嬪簭銆
Your Web browser caches pages, too. If a Web page sends out the appropriate headers, your browser will use the local cached copy for subsequent requests to that page, without even contacting the Web page again to see whether it has changed.
浣犵殑缃戦〉娴忚鍣ㄤ篃瀵归〉闈㈣繘琛岀紦瀛樸傚鏋滄煇缃戦〉閫佸嚭浜嗙浉搴旂殑澶撮儴锛屼綘鐨勬祻瑙堝櫒灏嗗湪涓哄璇ョ綉椤电殑鍚庣画鐨勮闂姹備娇鐢ㄦ湰鍦扮紦瀛樼殑鎷疯礉锛岀敋鑷充笉浼氬啀娆¤仈绯昏缃戦〉鏌ョ湅鏄惁鍙戠敓浜嗗彉鍖栥
Upstream caching is a nice efficiency boost, but theres a danger to it. The content of many Web pages differs based on authentication and a host of other variables, and cache systems that blindly save pages based purely on URLs could expose incorrect or sensitive data to subsequent visitors to those pages.
涓婃父缂撳瓨灏嗕細浜х敓闈炲父鏄庢樉鐨勬晥鐜囨彁鍗囷紝浣嗕篃瀛樺湪涓瀹氶闄┿傝澶氱綉椤电殑鍐呭渚濇嵁韬唤楠岃瘉浠ュ強璁稿鍏朵粬鍙橀噺鐨勬儏鍐靛彂鐢熷彉鍖栵紝缂撳瓨绯荤粺浠呯洸鐩湴鏍规嵁 URL 淇濆瓨椤甸潰锛屽彲鑳戒細鍚戣繖浜涢〉闈㈢殑鍚庣画璁块棶鑰呮毚闇蹭笉姝g‘鎴栬呮晱鎰熺殑鏁版嵁銆
For example, say you operate a Web e-mail system, and the contents of the inbox page obviously depend on which user is logged in. If an ISP blindly cached your site, then the first user who logged in through that ISP would have his or her user-specific inbox page cached for subsequent visitors to the site. Thats not cool.
涓句釜渚嬪瓙锛屽亣瀹氫綘鍦ㄤ娇鐢ㄧ綉椤电數閭郴缁燂紝鏄剧劧鏀朵欢绠遍〉闈㈢殑鍐呭鍙栧喅浜庣櫥褰曠殑鏄摢涓敤鎴枫傚鏋 ISP 鐩茬洰鍦扮紦瀛樹簡璇ョ珯鐐癸紝閭d箞绗竴涓敤鎴烽氳繃璇 ISP 鐧诲綍涔嬪悗锛屼粬锛堟垨濂癸級鐨勭敤鎴锋敹浠剁椤甸潰灏嗕細缂撳瓨缁欏悗缁殑璁块棶鑰呫傝繖涓鐐逛篃涓嶅ソ鐜┿
Fortunately, HTTP provides a solution to this problem. A number of HTTP headers exist to instruct upstream caches to differ their cache contents depending on designated variables, and to tell caching mechanisms not to cache particular pages. Well look at some of these headers in the sections that follow.
骞歌繍鐨勬槸锛 HTTP 鎻愪緵浜嗚В鍐宠闂鐨勬柟妗堛傚凡鏈変竴浜 HTTP 澶存爣鐢ㄤ簬鎸囧紩涓婃父缂撳瓨鏍规嵁鎸囧畾鍙橀噺鏉ュ尯鍒嗙紦瀛樺唴瀹癸紝骞堕氱煡缂撳瓨鏈哄埗涓嶅鐗瑰畾椤甸潰杩涜缂撳瓨銆傛垜浠皢鍦ㄦ湰鑺傚悗缁儴鍒嗗皢瀵硅繖浜涘ご鏍囪繘琛岄槓杩般
The Vary header defines which request headers a cache mechanism should take into account when building its cache key. For example, if the contents of a Web page depend on a users language preference, the page is said to vary on language.
Vary 澶存爣瀹氫箟浜嗙紦瀛樻満鍒跺湪鏋勫缓鍏剁紦瀛橀敭鍊兼椂搴斿綋灏嗗摢涓姹傚ご鏍囪冭檻鍦ㄥ唴銆備緥濡傦紝濡傛灉缃戦〉鐨勫唴瀹瑰彇鍐充簬鐢ㄦ埛鐨勮瑷鍋忓ソ锛岃椤甸潰琚О涓烘牴鎹瑷鑰屼笉鍚屻
By default, Djangos cache system creates its cache keys using the requested path (e.g., "/stories/2005/jun/23/bank_robbed/" ). This means every request to that URL will use the same cached version, regardless of user-agent differences such as cookies or language preferences. However, if this page produces different content based on some difference in request headerssuch as a cookie, or a language, or a user-agentyoull need to use the Vary header to tell caching mechanisms that the page output depends on those things.
Vary 澶存爣鏉ラ氱煡缂撳瓨鏈哄埗锛氳椤甸潰鐨勮緭鍑哄彇鍐充簬杩欎簺涓滆タ銆
To do this in Django, use the convenient vary_on_headers view decorator, like so:
瑕佸湪 Django 瀹屾垚杩欓」宸ヤ綔锛屽彲浣跨敤渚垮埄鐨 vary_on_headers 瑙嗗浘淇グ鍣紝濡備笅鎵绀猴細
from django.views.decorators.vary import vary_on_headers # Python 2.3 syntax. def my_view(request): # ... my_view = vary_on_headers(my_view, 'User-Agent') # Python 2.4+ decorator syntax. @vary_on_headers('User-Agent') def my_view(request): # ...
In this case, a caching mechanism (such as Djangos own cache middleware) will cache a separate version of the page for each unique user-agent.
鍦ㄨ繖绉嶆儏鍐典笅锛岀紦瀛樿缃紙濡 Django 鑷繁鐨勭紦瀛樹腑闂翠欢锛夊皢浼氫负姣忎竴涓崟鐙殑鐢ㄦ埛娴忚鍣ㄧ紦瀛樹竴涓嫭绔嬬殑椤甸潰鐗堟湰銆
The advantage to using the vary_on_headers decorator rather than manually setting the Vary header (using something like response['Vary'] = 'user-agent' ) is that the decorator adds to the Vary header (which may already exist), rather than setting it from scratch and potentially overriding anything that was already in there.
浣跨敤 vary_on_headers 淇グ鍣ㄨ屼笉鏄墜鍔ㄨ缃 Vary 澶存爣锛堜娇鐢ㄥ儚 response['Vary'] = 'user-agent' 涔嬬被鐨勪唬鐮侊級鐨勫ソ澶勬槸淇グ鍣ㄥ湪锛堝彲鑳藉凡缁忓瓨鍦ㄧ殑锛 Vary 涔嬩笂杩涜 娣诲姞 锛岃屼笉鏄粠闆跺紑濮嬭缃紝涓斿彲鑳借鐩栬澶勫凡缁忓瓨鍦ㄧ殑璁剧疆銆
You can pass multiple headers to vary_on_headers() :
浣犲彲浠ュ悜 vary_on_headers() 浼犲叆澶氫釜澶存爣锛
@vary_on_headers('User-Agent', 'Cookie') def my_view(request): # ...
This tells upstream caches to vary on both , which means each combination of user-agent and cookie will get its own cache value. For example, a request with the user-agent Mozilla and the cookie value foo=bar will be considered different from a request with the user-agent Mozilla and the cookie value foo=ham .
璇ユ浠g爜閫氱煡涓婃父缂撳瓨瀵 涓よ 閮借繘琛屼笉鍚屾搷浣滐紝涔熷氨鏄 user-agent 鍜 cookie 鐨勬瘡绉嶇粍鍚堥兘搴旇幏鍙栬嚜宸辩殑缂撳瓨鍊笺備妇渚嬫潵璇达紝浣跨敤 Mozilla 浣滀负 user-agent 鑰 foo=bar 浣滀负 cookie 鍊肩殑璇锋眰搴旇鍜屼娇鐢 Mozilla 浣滀负 user-agent 鑰 foo=ham 鐨勮姹傚簲璇ヨ瑙嗕负涓嶅悓璇锋眰銆
Because varying on cookie is so common, theres a vary_on_cookie decorator. These two views are equivalent:
鐢变簬鏍规嵁 cookie 鑰屽尯鍒嗗寰呮槸寰堝父瑙佺殑鎯呭喌锛屽洜姝ゆ湁 vary_on_cookie 淇グ鍣ㄣ備互涓嬩袱涓鍥炬槸绛夋晥鐨勶細
@vary_on_cookie def my_view(request): # ... @vary_on_headers('Cookie') def my_view(request): # ...
The headers you pass to vary_on_headers are not case sensitive; "User-Agent" is the same thing as "user-agent" .
浼犲叆 vary_on_headers 澶存爣鏄ぇ灏忓啓涓嶆晱鎰熺殑锛 "User-Agent" 涓 "user-agent" 瀹屽叏鐩稿悓銆
You can also use a helper function, django.utils.cache.patch_vary_headers , directly. This function sets, or adds to, the Vary header , for example:
浣犱篃鍙互鐩存帴浣跨敤甯姪鍑芥暟锛 django.utils.cache.patch_vary_headers 銆傝鍑芥暟璁剧疆鎴栧鍔 Vary header 锛屼緥濡傦細
from django.utils.cache import patch_vary_headers def my_view(request): # ... response = render_to_response('template_name', context) patch_vary_headers(response, ['Cookie']) return response
patch_vary_headers takes an HttpResponse instance as its first argument and a list/tuple of case-insensitive header names as its second argument.
patch_vary_headers 浠ヤ竴涓 HttpResponse 瀹炰緥涓虹涓涓弬鏁帮紝浠ヤ竴涓ぇ灏忓啓涓嶆晱鎰熺殑澶存爣鍚嶇О鍒楄〃鎴栧厓缁勪负绗簩涓弬鏁般
Other problems with caching are the privacy of data and the question of where data should be stored in a cascade of caches.
鍏充簬缂撳瓨鍓╀笅鐨勯棶棰樻槸鏁版嵁鐨勭闅愭т互鍙婂叧浜庡湪绾ц仈缂撳瓨涓暟鎹簲璇ュ湪浣曞鍌ㄥ瓨鐨勯棶棰樸
A user usually faces two kinds of caches: his or her own browser cache (a private cache) and his or her providers cache (a public cache). A public cache is used by multiple users and controlled by someone else. This poses problems with sensitive datayou dont want, say, your bank account number stored in a public cache. So Web applications need a way to tell caches which data is private and which is public.
閫氬父鐢ㄦ埛灏嗕細闈㈠涓ょ缂撳瓨锛氫粬鎴栧ス鑷繁鐨勬祻瑙堝櫒缂撳瓨锛堢鏈夌紦瀛橈級浠ュ強浠栨垨濂圭殑鎻愪緵鑰呯紦瀛橈紙鍏叡缂撳瓨锛夈傚叕鍏辩紦瀛樼敱澶氫釜鐢ㄦ埛浣跨敤锛岃屽彈鍏朵粬鏌愪汉鐨勬帶鍒躲傝繖灏变骇鐢熶簡浣犱笉鎯抽亣鍒扮殑鏁忔劅鏁版嵁鐨勯棶棰橈紝姣斿璇翠綘鐨勯摱琛岃处鍙疯瀛樺偍鍦ㄥ叕浼楃紦瀛樹腑銆傚洜姝わ紝Web 搴旂敤绋嬪簭闇瑕佷互鏌愮鏂瑰紡鍛婅瘔缂撳瓨閭d簺鏁版嵁鏄鏈夌殑锛屽摢浜涙槸鍏叡鐨勩
The solution is to indicate a pages cache should be private. To do this in Django, use the cache_control view decorator:
瑙e喅鏂规鏄爣绀哄嚭鏌愪釜椤甸潰缂撳瓨搴斿綋鏄鏈夌殑銆傝鍦 Django 涓畬鎴愭椤瑰伐浣滐紝鍙娇鐢 cache_control 瑙嗗浘淇グ鍣細
from django.views.decorators.cache import cache_control @cache_control(private=True) def my_view(request): # ...
This decorator takes care of sending out the appropriate HTTP header behind the scenes.
璇ヤ慨楗板櫒璐熻矗鍦ㄥ悗鍙板彂閫佺浉搴旂殑 HTTP 澶存爣銆
There are a few other ways to control cache parameters. For example, HTTP allows applications to do the following:
杩樻湁涓浜涘叾浠栨柟娉曞彲浠ユ帶鍒剁紦瀛樺弬鏁般備緥濡, HTTP 鍏佽搴旂敤绋嬪簭鎵ц濡備笅鎿嶄綔:
Define the maximum time a page should be cached.
瀹氫箟椤甸潰鍙互琚紦瀛樼殑鏈澶ф鏁般
Specify whether a cache should always check for newer versions, only delivering the cached content when there are no changes. (Some caches might deliver cached content even if the server page changed, simply because the cache copy isnt yet expired.)
鎸囧畾鏌愪釜缂撳瓨鏄惁鎬绘槸妫鏌ヨ緝鏂扮増鏈紝浠呭綋鏃犳洿鏂版椂鎵嶄紶閫掓墍缂撳瓨鍐呭銆傦紙涓浜涚紦瀛樺嵆渚垮湪鏈嶅姟鍣ㄩ〉闈㈠彂鐢熷彉鍖栫殑鎯呭喌涓嬮兘鍙兘杩樹細浼犻佹墍缂撳瓨鐨勫唴瀹癸紝鍙洜涓虹紦瀛樻嫹璐濇病鏈夎繃鏈熴傦級
In Django, use the cache_control view decorator to specify these cache parameters. In this example, cache_control tells caches to revalidate the cache on every access and to store cached versions for, at most, 3,600 seconds:
鍦 Django 涓紝鍙娇鐢 cache_control 瑙嗗浘淇グ鍣ㄦ寚瀹氳繖浜涚紦瀛樺弬鏁般傚湪鏈緥涓紝 cache_control 鍛婅瘔缂撳瓨瀵规瘡娆¤闂兘閲嶆柊楠岃瘉缂撳瓨骞跺湪鏈闀 3600 绉掑唴淇濆瓨鎵缂撳瓨鐗堟湰锛
from django.views.decorators.cache import cache_control @cache_control(must_revalidate=True, max_age=3600) def my_view(request): ...
Any valid Cache-Control HTTP directive is valid in cache_control() . Heres a full list:
鍦 cache_control() 涓紝浠讳綍鏈夋晥 Cache-Control HTTP 鎸囦护閮芥槸鏈夋晥鐨勩備互涓嬫槸涓涓畬鏁寸殑娓呭崟锛
public=True
public=True
private=True
private=True
no_cache=True
no_cache=True
no_transform=True
no_transform=True
must_revalidate=True
must_revalidate=True
proxy_revalidate=True
proxy_revalidate=True
max_age=num_seconds
max_age=num_seconds
s_maxage=num_seconds
s_maxage=num_seconds
Tip
灏忔彁绀
For explanation of Cache-Control HTTP directives, see the specification at http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.
瑕佷簡瑙f湁鍏 Cache-Control HTTP 鎸囦护鐨勭浉鍏宠В閲, 鍙互鏌ラ槄 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 鐨勮鑼冩枃妗c
Note
娉ㄦ剰
The caching middleware already sets the cache headers max-age with the value of the CACHE_MIDDLEWARE_SETTINGS setting. If you use a custom max_age in a cache_control decorator, the decorator will take precedence, and the header values will be merged correctly.)
缂撳瓨涓棿浠跺凡缁忎娇鐢 CACHE_MIDDLEWARE_SETTINGS 璁剧疆璁惧畾浜嗙紦瀛樺ご鏍 max-age 銆傚鏋滀綘鍦 cache_control 淇グ鍣ㄤ腑浣跨敤浜嗚嚜瀹氫箟鐨 max_age 锛岃淇グ鍣ㄥ皢浼氬彇寰椾紭鍏堟潈锛岃澶存爣鐨勫煎皢琚纭湴琚悎骞躲傦級
Django comes with a few other pieces of middleware that can help optimize your applications performance:
Django 甯︽湁涓浜涘叾瀹冧腑闂翠欢鍙府鍔╂偍浼樺寲搴旂敤绋嬪簭鐨勬ц兘:
django.middleware.http.ConditionalGetMiddleware adds support for modern browsers to conditionally GET responses based on the ETag and Last-Modified headers.
django.middleware.http.ConditionalGetMiddleware 涓虹幇浠f祻瑙堝櫒澧炲姞浜嗘湁鏉′欢鍦 GET 鍩轰簬 ETag 鍜 Last-Modified 澶存爣鐨勫搷搴旂殑鐩稿叧鏀寔銆
django.middleware.gzip.GZipMiddleware compresses responses for all moderns browsers, saving bandwidth and transfer time.
django.middleware.gzip.GZipMiddleware 涓烘墍鏈夌幇浠f祻瑙堝櫒鍘嬬缉鍝嶅簲鍐呭锛屼互鑺傜渷甯﹀鍜屼紶閫佹椂闂淬
If you use CacheMiddleware , its important to put it in the right place within the MIDDLEWARE_CLASSES setting, because the cache middleware needs to know the headers by which to vary the cache storage.
濡傛灉浣跨敤缂撳瓨涓棿浠讹紝涓瀹氳灏嗗叾鏀剧疆鍦 MIDDLEWARE_CLASSES 璁剧疆鐨勬纭綅缃紝鍥犱负缂撳瓨涓棿浠堕渶瑕佺煡閬撶敤浜庝骇鐢熶笉鍚岀紦瀛樺瓨鍌ㄧ殑鐨勫ご鏍囥
Put the CacheMiddleware after any middlewares that might add something to the Vary header, including the following:
灏 CacheMiddleware 鏀剧疆鍦ㄦ墍鏈夊彲鑳藉悜 Vary 澶存爣娣诲姞鍐呭鐨勪腑闂翠欢涔嬪悗锛屽寘鎷笅鍒椾腑闂翠欢锛
SessionMiddleware , which adds Cookie
娣诲姞 Cookie 鐨 SessionMiddleware
GZipMiddleware , which adds Accept-Encoding
娣诲姞 Accept-Encoding 鐨 GZipMiddleware ,
Django ships with a number of contrib packagescool, optional features. Weve already covered a few of the: the admin system (Chapter 6) and the session/user framework (Chapter 11).
Django 甯︽湁涓浜涘姛鑳藉寘瑁呬簡涓浜涘緢閰风殑,鍙夌殑鐗硅壊. 鎴戜滑宸茬粡璁蹭簡涓浜: admin绯荤粺(绗6绔)鍜宻ession/user妗嗘灦(绗11绔).
The next chapter covers the rest of the contributed subframeworks. Theres a lot of cool tools available; you wont want to miss any of them.
涓嬩竴绔犱腑锛屾垜浠皢璁茶堪Django涓叾浠栫殑瀛愭鏋讹紝灏嗕細鏈夊緢澶氬緢閰风殑宸ュ叿鍑虹幇锛屼綘涓瀹氫笉鎯抽敊杩囧畠浠
鍏充簬鏈瘎娉ㄧ郴缁
鏈珯浣跨敤涓婁笅鏂囧叧鑱旂殑璇勬敞绯荤粺鏉ユ敹闆嗗弽棣堜俊鎭備笉鍚屼簬涓鑸鏁寸珷鍋氳瘎娉ㄧ殑鍋氭硶锛 鎴戜滑鍏佽浣犲姣忎竴涓嫭绔嬬殑鈥滄枃鏈潡鈥濆仛璇勬敞銆備竴涓滄枃鏈潡鈥濈湅璧锋潵鏄繖鏍风殑锛
涓涓滄枃鏈潡鈥濇槸涓涓钀斤紝涓涓垪琛ㄩ」锛屼竴娈典唬鐮侊紝鎴栬呭叾浠栦竴灏忔鍐呭銆 浣犻変腑瀹冧細楂樹寒搴︽樉绀:
瑕佸鏂囨湰鍧楀仛璇勬敞锛屼綘鍙渶瑕佺偣鍑诲畠鏃佽竟鐨勬爣璇嗗潡:
鎴戜滑浼氫粩缁嗛槄璇绘瘡涓瘎璁猴紝濡傛灉鍙兘鐨勮瘽鎴戜滑涔熶細鎶婅瘎娉ㄨ冭檻鍒版湭鏉ョ殑鐗堟湰涓幓:
濡傛灉浣犳効鎰忎綘鐨勮瘎娉ㄨ閲囩敤锛岃纭繚鐣欎笅浣犵殑鍏ㄥ悕 (娉ㄦ剰涓嶆槸鏄电О鎴栫畝绉帮級
Many, many thanks to Jack Slocum; the inspiration and much of the code for the comment system comes from Jack's blog, and this site couldn't have been built without his wonderful
YAHOO.ext
library. Thanks also to Yahoo for YUI itself.