Usually when we talk about developing Web sites, were talking about producing HTML. Of course, theres a lot more to the Web than HTML; we use the Web to distribute data in all sorts of formats: RSS, PDFs, images, and so forth.
閫氬父褰撴垜浠皥鍒板紑鍙戠綉绔欐椂锛屼富瑕佽皥璁虹殑鏄疕TML銆傚綋鐒讹紝Web杩滀笉鍙湁HTML锛屾垜浠湪Web涓婄敤澶氱鏍煎紡鏉ュ彂甯冩暟鎹細RSS銆丳DF銆佸浘鐗囩瓑銆
So far weve focused on the common case of HTML production, but in this chapter well take a detour and look at using Django to produce other types of content.
鍒扮洰鍓嶄负姝紝鎴戜滑鐨勬敞鎰忓姏閮芥槸鏀惧湪甯歌 HTML 浠g爜鐢熸垚涓婏紝浣嗘槸鍦ㄨ繖涓绔犱腑锛屾垜浠皢浼氬浣跨敤 Django 鐢熸垚鍏跺畠鏍煎紡鐨勫唴瀹硅繘琛岀畝瑕佷粙缁嶃
Django has convenient built-in tools that you can use to produce some common non-HTML content:
Django鎷ユ湁涓浜涗究鍒╃殑鍐呭缓宸ュ叿甯姪浣犵敓鎴愬父瑙佺殑闈濰TML鍐呭锛
RSS/Atom syndication feeds
RSS/Atom 鑱氬悎鏂囦欢
Sitemaps (an XML format originally developed by Google that gives hints to search engines)
绔欑偣鍦板浘 锛堜竴涓猉ML鏍煎紡鏂囦欢锛屾渶鍒濈敱Google寮鍙戯紝鐢ㄤ簬缁欐悳绱㈠紩鎿庢彁绀虹嚎绱級
Well examine each of those tools a little later on, but first well cover the basic principles.
鎴戜滑绋嶅悗浼氶愪竴鐮旂┒杩欎簺宸ュ叿锛屼笉杩囬鍏堣鎴戜滑鏉ヤ簡瑙d簺鍩虹鍘熺悊銆
Remember this from Chapter 3?
杩樿寰楃涓夌珷鐨勫唴瀹瑰悧锛
A view function, or view for short, is simply a Python function that takes a Web request and returns a Web response. This response can be the HTML contents of a Web page, or a redirect, or a 404 error, or an XML document, or an imageor anything, really.
涓涓鍥惧嚱鏁帮紙view function锛夛紝鎴栬呯畝绉 view 锛屽彧涓嶈繃鏄竴涓彲浠ュ鐞嗕竴涓猈eb璇锋眰骞朵笖杩斿洖 涓涓猈eb鍝嶅簲鐨凱ython鍑芥暟銆傝繖涓搷搴斿彲浠ユ槸涓涓猈eb椤甸潰鐨凥TML鍐呭锛屾垨鑰呬竴涓烦杞紝鎴栬呬竴涓404 閿欒锛屾垨鑰呬竴涓猉ML鏂囨。锛屾垨鑰呬竴骞呭浘鐗囷紝鎴栬呮槧灏勫埌浠讳綍涓滆タ涓娿
More formally, a Django view function must
鏇存寮忕殑璇达紝涓涓狣jango瑙嗗浘鍑芥暟 蹇呴』
Accept an HttpRequest instance as its first argument
鎺ュ彈涓涓 HttpRequest 瀹炰緥浣滀负瀹冪殑绗竴涓弬鏁
Return an HttpResponse instance
杩斿洖涓涓 HttpResponse 瀹炰緥
The key to returning non-HTML content from a view lies in the HttpResponse class, specifically the mimetype constructor argument. By tweaking the MIME type, we can indicate to the browser that weve returned a response of a different format.
浠庝竴涓鍥捐繑鍥炰竴涓潪 HTML 鍐呭鐨勫叧閿槸鍦ㄦ瀯閫犱竴涓 HttpResponse 绫绘椂锛岄渶瑕佹寚瀹 mimetype 鍙傛暟銆傞氳繃鏀瑰彉 MIME 绫诲瀷锛屾垜浠彲浠ュ憡鐭ユ祻瑙堝櫒灏嗚杩斿洖鐨勬暟鎹槸鍙︿竴绉嶄笉鍚岀殑绫诲瀷銆
For example, lets look at a view that returns a PNG image. To keep things simple, well just read the file off the disk:
涓嬮潰鎴戜滑浠ヨ繑鍥炰竴寮燩NG鍥剧墖鐨勮鍥句负渚嬨備负浜嗕娇浜嬫儏鑳藉敖鍙兘鐨勭畝鍗曪紝鎴戜滑鍙槸璇诲叆涓寮犲瓨鍌ㄥ湪纾佺洏涓婄殑鍥剧墖锛
from django.http import HttpResponse def my_image(request): image_data = open("/path/to/my/image.png", "rb").read() return HttpResponse(image_data, mimetype="image/png")
Thats it! If you replace the image path in the open() call with a path to a real image, you can use this very simple view to serve an image, and the browser will display it correctly.
灏辨槸杩欎箞绠鍗曘傚鏋滄敼鍙 open() 涓殑鍥剧墖璺緞涓轰竴寮犵湡瀹炲浘鐗囩殑璺緞锛岄偅涔堝氨鍙互浣跨敤杩欎釜鍗佸垎绠鍗曠殑瑙嗗浘鏉ユ彁渚涗竴寮犲浘鐗囷紝骞朵笖娴忚鍣ㄥ彲浠ユ纭殑鏄剧ず瀹冦
The other important thing to keep in mind is that HttpResponse objects implement Pythons standard file API. This means that you can use an HttpResponse instance in any place Python (or a third-party library) expects a file.
鍙﹀鎴戜滑蹇呴』浜嗚В鐨勬槸”HttpResponse”瀵硅薄搴旂敤浜哖ython鏍囧噯鐨勬枃浠跺簲鐢ㄧ▼搴忔帴鍙(API)銆傝繖灏辨槸璇翠綘鍙互鍦≒ython锛堟垨绗笁鏂瑰簱锛変换浣曠敤鍒版枃浠剁殑鍦版柟浣跨敤”HttpResponse”瀹炰緥銆
For an example of how that works, lets take a look at producing CSV with Django.
涓嬮潰灏嗙敤 Django 鐢熸垚 CSV 鏂囦欢涓轰緥锛岃鏄庡畠鐨勫伐浣滃師鐞嗐
CSV is a simple data format usually used by spreadsheet software. Its basically a series of table rows, with each cell in the row separated by a comma (CSV stands for comma-separated values ). For example, heres some data on unruly airline passengers in CSV format:
CSV 鏄竴绉嶇畝鍗曠殑鏁版嵁鏍煎紡锛岄氬父涓虹數瀛愯〃鏍艰蒋浠舵墍浣跨敤銆傚畠涓昏鏄敱涓绯诲垪鐨勮〃鏍艰缁勬垚锛屾瘡琛屼腑鍗曞厓鏍间箣闂翠娇鐢ㄩ楀彿(CSV 鏄 閫楀彿鍒嗛殧鏁板(comma-separated values) 鐨勭缉鍐)闅斿紑銆備緥濡傦紝涓嬮潰鏄互 CSV 鏍煎紡璁板綍鐨勪竴浜涜繚瑙勮埅鐝箻瀹㈢殑鏁版嵁銆
Year,Unruly Airline Passengers 1995,146 1996,184 1997,235 1998,200 1999,226 2000,251 2001,299 2002,273 2003,281 2004,304 2005,203
Note
澶囨敞
The preceding listing contains real numbers; they come courtesy of the US Federal Aviation Administration. See http://www.faa.gov/data_statistics/passengers_cargo/unruly_passengers/.
鍓嶉潰鐨勫垪琛ㄦ槸鐪熷疄鐨勬暟鎹紝鏁版嵁鐢辩編鍥借仈閭﹁埅绌虹鐞嗗鎻愪緵銆傚叿浣撳唴瀹硅鍙傝 http://www.faa.gov/data_statistics/passengers_cargo/unruly_passengers/.
Though CSV looks simple, its not a format thats ever been formally defined. Different pieces of software produce and consume different variants of CSV, making it a bit tricky to use. Luckily, Python comes with a standard CSV library, csv , that is pretty much bulletproof.
铏界劧 CSV 鐪嬩笂鍘荤畝鍗曪紝浠ヨ嚦浜庣畝鍗曞埌杩欎釜鏍煎紡鐢氳嚦閮芥病鏈夋寮忕殑瀹氫箟銆備絾鏄笉鍚岀殑杞欢浼氱敓鎴愬拰浣跨敤涓嶅悓鐨 CSV 鐨勫彉绉嶏紝鍦ㄤ娇鐢ㄤ笂浼氭湁涓浜涗笉渚裤傚垢杩愮殑鏄紝 Python 浣跨敤鐨勬槸鏍囧噯 CSV 搴擄紝 csv 锛屾墍浠ュ畠鏇撮氱敤銆
Because the csv module operates on file-like objects, its a snap to use an HttpResponse instead:
鍥犱负 csv 妯″潡鎿嶄綔鐨勬槸绫讳技鏂囦欢鐨勫璞★紝鎵浠ュ彲浠ヤ娇鐢 HttpResponse 鏇挎崲锛
import csv from django.http import HttpResponse # Number of unruly passengers each year 1995 - 2005. In a real application # this would likely come from a database or some other back-end data store. UNRULY_PASSENGERS = [146,184,235,200,226,251,299,273,281,304,203] def unruly_passengers_csv(request): # Create the HttpResponse object with the appropriate CSV header. response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=unruly.csv' # Create the CSV writer using the HttpResponse as the "file" writer = csv.writer(response) writer.writerow(['Year', 'Unruly Airline Passengers']) for (year, num) in zip(range(1995, 2006), UNRULY_PASSENGERS): writer.writerow([year, num]) return response
The code and comments should be pretty clear, but a few things deserve special mention:
浠g爜鍜屾敞閲婂彲浠ヨ鏄緢娓呮锛屼絾杩樻湁涓浜涗簨鎯呴渶瑕佺壒鍒敞鎰忥細
The response is given the text/csv MIME type (instead of the default text/html ). This tells browsers that the document is a CSV file.
鍝嶅簲杩斿洖鐨勬槸 text/csv MIME绫诲瀷锛堣岄潪榛樿鐨 text/html 锛夈傝繖浼氬憡璇夋祻瑙堝櫒锛岃繑鍥炵殑鏂囨。鏄疌SV鏂囦欢銆
The response gets an additional Content-Disposition header, which contains the name of the CSV file. This header (well, the attachment part) will instruct the browser to prompt for a location to save the file (instead of just displaying it). This file name is arbitrary; call it whatever you want. It will be used by browsers in the Save As dialog.
鍝嶅簲浼氭湁涓涓檮鍔犵殑 Content-Disposition 澶撮儴锛屽畠鍖呭惈鏈塁SV鏂囦欢鐨勬枃浠跺悕銆傝繖涓ご閮紙鎴栬呰锛岄檮鍔犻儴鍒嗭級浼氭寚绀烘祻瑙堝櫒寮瑰嚭瀵硅瘽妗嗚闂枃浠跺瓨鏀剧殑浣嶇疆锛堣屼笉浠呬粎鏄樉绀猴級銆傝繖涓枃浠跺悕鏄换鎰忕殑锛屽畠浼氱敤鍦ㄦ祻瑙堝櫒鐨勫彟瀛樹负瀵硅瘽妗嗕腑銆
Hooking into the CSV-generation API is easy: just pass response as the first argument to csv.writer . The csv.writer function expects a filelike object, and HttpResponse objects fit the bill.
涓庡垱寤篊SV鐨勫簲鐢ㄧ▼搴忕晫闈紙API锛夋寕鎺ユ槸寰堝鏄撶殑锛氬彧闇灏 response 浣滀负绗竴涓彉閲忎紶閫掔粰 csv.writer 銆 csv.writer 鍑芥暟甯屾湜鑾峰緱涓涓枃浠剁被鐨勫璞★紝 HttpResponse 姝eソ鑳借揪鎴愯繖涓洰鐨勩
For each row in your CSV file, call writer.writerow , passing it an iterable object such as a list or tuple.
璋冪敤 writer.writerow 锛屽苟涓斾紶閫掔粰瀹冧竴涓被浼 list 鎴栬 tuple 鐨勫彲杩唬瀵硅薄锛屽氨鍙互鍦 CSV 鏂囦欢涓啓鍏ヤ竴琛屻
The CSV module takes care of quoting for you, so you dont have to worry about escaping strings with quotes or commas in them. Just pass information to writerow() , and it will do the right thing.
CSV 妯″潡鑰冭檻鍒颁簡寮曠敤鐨勯棶棰橈紝鎵浠ユ偍涓嶇敤鎷呭績閫稿嚭瀛楃涓蹭腑寮曞彿鍜岄楀彿銆傚彧瑕佹妸淇℃伅浼犻掔粰 writerow() 锛屽畠浼氬鐞嗗ソ鎵鏈夌殑浜嬫儏銆
This is the general pattern youll use any time you need to return non-HTML content: create an HttpResponse response object (with a special MIME type), pass it to something expecting a file, and then return the response.
鍦ㄤ换浣曢渶瑕佽繑鍥為潪 HTML 鍐呭鐨勬椂鍊欙紝閮介渶瑕佺粡杩囦互涓嬪嚑姝ワ細鍒涘缓涓涓 HttpResponse 鍝嶅簲瀵硅薄锛堥渶瑕佹寚瀹氱壒娈婄殑 MIME 绫诲瀷锛夈傚皢瀹冧綔涓哄弬鏁颁紶缁欎竴涓渶瑕佹枃浠剁殑鏂规硶锛岀劧鍚庤繑鍥炶繖涓搷搴斻
Lets look at a few more examples.
涓嬮潰鏄竴浜涘叾瀹冪殑渚嬪瓙
Portable Document Format (PDF) is a format developed by Adobe thats used to represent printable documents, complete with pixel-perfect formatting, embedded fonts, and 2D vector graphics. You can think of a PDF document as the digital equivalent of a printed document; indeed, PDFs are usually used when you need to give a document to someone else to print.
渚挎惡鏂囦欢鏍煎紡 (PDF) 鏄敱 Adobe 寮鍙戠殑鏍煎紡锛屼富瑕佺敤浜庡憟鐜板彲鎵撳嵃鐨勬枃妗o紝鍖呭惈鏈 pixel-perfect 鏍煎紡锛屽祵鍏ュ瓧浣撲互鍙2D鐭㈤噺鍥惧儚銆侾DF 鏂囦欢鍙互琚涓烘槸涓浠芥墦鍗版枃妗g殑鏁板瓧绛変环鐗╋紱瀹為檯涓婏紝PDF 鏂囦欢閫氬父鐢ㄤ簬闇瑕佸皢鏂囨。浜や粯缁欏叾浠栦汉鍘绘墦鍗扮殑鍦哄悎銆
You can easily generate PDFs with Python and Django thanks to the excellent open source ReportLab library (http://www.reportlab.org/rl_toolkit.html). The advantage of generating PDF files dynamically is that you can create customized PDFs for different purposes say, for different users or different pieces of content.
渚挎惡鏂囦欢鏍煎紡 (PDF) 鏄敱 Adobe 寮鍙戠殑鏍煎紡锛屼富瑕佺敤浜庡憟鐜板彲鎵撳嵃鐨勬枃妗o紝鍖呭惈鏈 pixel-perfect 鏍煎紡锛屽祵鍏ュ瓧浣撲互鍙2D鐭㈤噺鍥惧儚銆侾DF 鏂囦欢鍙互琚涓烘槸涓浠芥墦鍗版枃妗g殑鏁板瓧绛変环鐗╋紱瀹為檯涓婏紝PDF 鏂囦欢閫氬父鐢ㄤ簬闇瑕佸皢鏂囨。浜や粯缁欏叾浠栦汉鍘绘墦鍗扮殑鍦哄悎銆
For example, we used Django and ReportLab at KUSports.com to generate customized, printer-ready NCAA tournament brackets.
涓嬮潰鐨勪緥瀛愭槸浣跨敤 Django 鍜 ReportLab 鍦 KUSports.com 涓婄敓鎴愪釜鎬у寲鐨勫彲鎵撳嵃鐨 NCAA 璧涚▼琛 (tournament brackets) 銆
Before you do any PDF generation, however, youll need to install ReportLab. Its usually pretty simple: just download and install the library from http://www.reportlab.org/downloads.html.
鍦ㄧ敓鎴 PDF 鏂囦欢涔嬪墠锛岄渶瑕佸畨瑁 ReportLab 搴撱傝繖閫氬父鏄釜寰堢畝鍗曠殑杩囩▼锛氫粠 http://www.reportlab.org/downloads.html 涓嬭浇骞朵笖瀹夎杩欎釜搴撳嵆鍙
The user guide (naturally available only as a PDF file) at http://www.reportlab.org/rsrc/userguide.pdf has additional installation instructions.
浣跨敤鎵嬪唽锛堝師濮嬬殑鍙湁 PDF 鏍煎紡锛夊彲浠ヤ粠 http://www.reportlab.org/rsrc/userguide.pdf 涓嬭浇锛屽叾涓寘鍚湁涓浜涘叾瀹冪殑瀹夎鎸囧崡銆
Note
娉ㄦ剰
If youre using a modern Linux distribution, you might want to check your package management utility before installing ReportLab. Most package repositories have added ReportLab.
濡傛灉浣跨敤鐨勬槸涓浜涙柊鐨 Linux 鍙戣鐗堬紝鍒欏湪瀹夎鍓嶅彲浠ュ厛妫鏌ュ寘绠$悊杞欢銆傚鏁拌蒋浠跺寘浠撳簱涓兘鍔犲叆浜 ReportLab 銆
For example, if youre using the (excellent) Ubuntu distribution, a simple apt-get install python-reportlab will do the trick nicely.
姣斿锛屽鏋滀娇鐢紙鏉板嚭鐨勶級 Ubuntu 鍙戣鐗堬紝鍙渶瑕佺畝鍗曠殑 apt-get install python-reportlab 涓琛屽懡浠ゅ嵆鍙畬鎴愬畨瑁呫
Test your installation by importing it in the Python interactive interpreter:
鍦 Python 浜や簰鐜涓鍏ヨ繖涓蒋浠跺寘浠ユ鏌ュ畨瑁呮槸鍚︽垚鍔熴
>>> import reportlab
If that command doesnt raise any errors, the installation worked.
濡傛灉鍒氭墠閭f潯鍛戒护娌℃湁鍑虹幇浠讳綍閿欒锛屽垯琛ㄦ槑瀹夎鎴愬姛銆
Like CSV, generating PDFs dynamically with Django is easy because the ReportLab API acts on filelike objects.
鍜 CSV 绫讳技锛岀敱 Django 鍔ㄦ佺敓鎴 PDF 鏂囦欢寰堢畝鍗曪紝鍥犱负 ReportLab API 鍚屾牱鍙互浣跨敤绫讳技鏂囦欢瀵硅薄銆
Heres a Hello World example:
涓嬮潰鏄竴涓 Hello World 鐨勭ず渚嬶細
from reportlab.pdfgen import canvas from django.http import HttpResponse def hello_pdf(request): # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename=hello.pdf' # Create the PDF object, using the response object as its "file." p = canvas.Canvas(response) # Draw things on the PDF. Here's where the PDF generation happens. # See the ReportLab documentation for the full list of functionality. p.drawString(100, 100, "Hello world.") # Close the PDF object cleanly, and we're done. p.showPage() p.save() return response
A few notes are in order:
闇瑕佹敞鎰忎互涓嬪嚑鐐癸細
Here we use the application/pdf MIME type. This tells browsers that the document is a PDF file, rather than an HTML file. If you leave off this information, browsers will probably interpret the response as HTML, which will result in scary gobbledygook in the browser window.
杩欓噷鎴戜滑浣跨敤鐨 MIME 绫诲瀷鏄 application/pdf 銆傝繖浼氬憡璇夋祻瑙堝櫒杩欎釜鏂囨。鏄竴涓 PDF 鏂囨。锛岃屼笉鏄 HTML 鏂囨。銆傚鏋滃拷鐣ヤ簡杩欎釜鍙傛暟锛屾祻瑙堝櫒鍙兘浼氭妸杩欎釜鏂囦欢鐪嬫垚 HTML 鏂囨。锛岃繖浼氫娇娴忚鍣ㄧ殑绐楀彛涓嚭鐜板緢濂囨殑鏂囧瓧銆
Hooking into the ReportLab API is easy: just pass response as the first argument to canvas.Canvas . The Canvas class expects a filelike object, and HttpResponse objects fit the bill.
浣跨敤 ReportLab 鐨 API 寰堢畝鍗曪細鍙渶瑕佸皢 response 瀵硅薄浣滀负 canvas.Canvas 鐨勭涓涓弬鏁颁紶鍏ャ Canvas 绫婚渶瑕佷竴涓被浼兼枃浠剁殑瀵硅薄锛 HttpResponse 瀵硅薄鍙互婊¤冻杩欎釜瑕佹眰銆
All subsequent PDF-generation methods are called on the PDF object (in this case, p ), not on response .
鎵鏈夊悗缁殑 PDF 鐢熸垚鏂规硶闇瑕佺敱 PDF 瀵硅薄璋冪敤锛堝湪鏈緥涓槸 p 锛夛紝鑰屼笉鏄 response 瀵硅薄銆
Finally, its important to call showPage() and save() on the PDF file (or else youll end up with a corrupted PDF file).
鏈鍚庨渶瑕佸 PDF 鏂囦欢璋冪敤 showPage() 鍜 save() 鏂规硶锛堝惁鍒欎綘浼氬緱鍒颁竴涓崯鍧忕殑 PDF 鏂囦欢锛夈
If youre creating a complex PDF document (or any large data blob), consider using the cStringIO library as a temporary holding place for your PDF file. The cStringIO library provides a file-like object interface that is written in C for maximum efficiency.
濡傛灉鎮ㄥ湪鍒涘缓涓涓鏉傜殑 PDF 鏂囨。锛堟垨鑰呬换浣曡緝澶х殑鏁版嵁鍧楋級锛岃浣跨敤 cStringIO 搴撳瓨鏀句复鏃剁敓鎴愮殑 PDF 鏂囦欢銆 cStringIO 鎻愪緵浜嗕竴涓敤 C 缂栧啓鐨勭被浼兼枃浠跺璞$殑鎺ュ彛锛屼粠鑰屽彲浠ヤ娇绯荤粺鐨勬晥鐜囨渶楂樸
Heres the previous Hello World example rewritten to use cStringIO :
涓嬮潰鏄娇鐢 cStringIO 閲嶅啓鐨 Hello World 渚嬪瓙锛
from cStringIO import StringIO from reportlab.pdfgen import canvas from django.http import HttpResponse def hello_pdf(request): # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename=hello.pdf' temp = StringIO() # Create the PDF object, using the StringIO object as its "file." p = canvas.Canvas(temp) # Draw things on the PDF. Here's where the PDF generation happens. # See the ReportLab documentation for the full list of functionality. p.drawString(100, 100, "Hello world.") # Close the PDF object cleanly. p.showPage() p.save() # Get the value of the StringIO buffer and write it to the response. response.write(temp.getvalue()) return response
Theres a whole host of other types of content you can generate in Python. Here are a few more ideas and some pointers to libraries you could use to implement them:
浣跨敤 Python 鍙互鐢熸垚璁稿鍏跺畠绫诲瀷鐨勫唴瀹癸紝涓嬮潰浠嬬粛鐨勬槸涓浜涘叾瀹冪殑鎯虫硶鍜屼竴浜涘彲浠ョ敤浠ュ疄鐜板畠浠殑搴撱
ZIP files : Pythons standard library ships with the zipfile module, which can both read and write compressed ZIP files. You could use it to provide on-demand archives of a bunch of files, or perhaps compress large documents when requested. You could similarly produce TAR files using the standard library tarfile module.
ZIP 鏂囦欢 锛歅ython 鏍囧噯搴撲腑鍖呭惈鏈 zipfile 妯″潡锛屽畠鍙互璇诲拰鍐欏帇缂╃殑 ZIP 鏂囦欢銆傚畠鍙互鐢ㄤ簬鎸夐渶鐢熸垚涓浜涙枃浠剁殑鍘嬬缉鍖咃紝鎴栬呭湪闇瑕佹椂鍘嬬缉澶х殑鏂囨。銆傚鏋滄槸 TAR 鏂囦欢鍒欏彲浠ヤ娇鐢ㄦ爣鍑嗗簱 tarfile 妯″潡銆
Dynamic images : The Python Imaging Library (PIL; http://www.pythonware.com/products/pil/) is a fantastic toolkit for producing images (PNG, JPEG, GIF, and a whole lot more). You could use it to automatically scale down images into thumbnails, composite multiple images into a single frame, or even do Web-based image processing.
鍔ㄦ佸浘鐗 锛 Python 鍥剧墖澶勭悊搴 (PIL; http://www.pythonware.com/products/pil/) 鏄瀬濂界殑鐢熸垚鍥剧墖(PNG, JPEG, GIF 浠ュ強鍏跺畠璁稿鏍煎紡)鐨勫伐鍏枫傚畠鍙互鐢ㄤ簬鑷姩涓哄浘鐗囩敓鎴愮缉鐣ュ浘锛屽皢澶氬紶鍥剧墖鍘嬬缉鍒板崟鐙殑妗嗘灦涓紝鎴栬呮槸鍋氬熀浜 Web 鐨勫浘鐗囧鐞嗐
Plots and charts : There are a number of incredibly powerful Python plotting and charting libraries you could use to produce on-demand maps, charts, plots, and graphs. We cant possibly list them all, so here are a couple of the highlights:
鍥捐〃 锛 Python 鏈夎澶氬嚭鑹插苟涓斿己澶х殑鍥捐〃搴撶敤浠ョ粯鍒跺浘琛紝鎸夐渶鍦板浘锛岃〃鏍肩瓑銆傛垜浠笉鍙兘灏嗗畠浠叏閮ㄥ垪鍑猴紝鎵浠ヤ笅闈㈠垪鍑虹殑鏄釜涓殑缈樻銆
matplotlib (http://matplotlib.sourceforge.net/) can be used to produce the type of high-quality plots usually generated with MatLab or Mathematica.
matplotlib (http://matplotlib.sourceforge.net/) 鍙互鐢ㄤ簬鐢熸垚閫氬父鏄敱 matlab 鎴栬 Mathematica 鐢熸垚鐨勯珮璐ㄩ噺鍥捐〃銆
pygraphviz (https://networkx.lanl.gov/wiki/pygraphviz), an interface to the Graphviz graph layout toolkit (http://graphviz.org/), can be used for generating structured diagrams of graphs and networks.
pygraphviz (https://networkx.lanl.gov/wiki/pygraphviz) 鏄竴涓 Graphviz 鍥惧舰甯冨眬鐨勫伐鍏 (http://graphviz.org/) 鐨 Python 鎺ュ彛锛屽彲浠ョ敤浜庣敓鎴愮粨鏋勫寲鐨勫浘琛ㄥ拰缃戠粶銆
In general, any Python library capable of writing to a file can be hooked into Django. The possibilities really are endless.
鎬讳箣锛屾墍鏈夊彲浠ュ啓鏂囦欢鐨勫簱閮藉彲浠ヤ笌 Django 鍚屾椂浣跨敤銆傝鐩镐俊涓鍒囩殕鏈夊彲鑳姐
Now that weve looked at the basics of generating non-HTML content, lets step up a level of abstraction. Django ships with some pretty nifty built-in tools for generating some common types of non-HTML content.
鎴戜滑宸茬粡浜嗚В浜嗙敓鎴愨滈潪HTML鈥濆唴瀹圭殑鍩烘湰鐭ヨ瘑锛岃鎴戜滑杩涗竴姝ユ荤粨涓涓嬨侱jango鎷ユ湁寰堝鐢ㄤ互鐢熸垚鍚勭被鈥滈潪HTML鈥濆唴瀹圭殑鍐呯疆宸ュ叿銆
Django comes with a high-level syndication-feed-generating framework that makes creating RSS and Atom feeds easy.
Django甯︽潵浜嗕竴涓珮绾х殑鑱氬悎鐢熸垚妗嗘灦锛屽畠浣垮緱鍒涘缓RSS鍜孉tom feeds鍙樺緱闈炲父瀹规槗銆
Whats RSS? Whats Atom?
浠涔堟槸RSS锛熶粈涔堟槸Atom锛
RSS and Atom are both XML-based formats you can use to provide automatically updating feeds of your sites content. Read more about RSS at http://www.whatisrss.com/, and get information on Atom at http://www.atomenabled.org/.
RSS鍜孉tom閮芥槸鍩轰簬XML鐨勬牸寮忥紝浣犲彲浠ョ敤瀹冩潵鎻愪緵鏈夊叧浣犵珯鐐瑰唴瀹圭殑鑷姩鏇存柊鐨刦eed銆備簡瑙f洿澶氬叧浜嶳SS鐨勫彲浠ヨ闂 http://www.whatisrss.com/, 鏇村Atom鐨勪俊鎭彲浠ヨ闂 http://www.atomenabled.org/.
To create any syndication feed, all you have to do is write a short Python class. You can create as many feeds as you want.
鎯冲垱寤轰竴涓仈鍚堜緵绋跨殑婧(syndication feed)锛屾墍闇瑕佸仛鐨勫彧鏄啓涓涓畝鐭殑python绫汇備綘鍙互鍒涘缓浠绘剰澶氱殑婧(feed)銆
The high-level feed-generating framework is a view thats hooked to /feeds/ by convention. Django uses the remainder of the URL (everything after /feeds/ ) to determine which feed to return.
楂樼骇feed鐢熸垚妗嗘灦鏄竴涓粯璁ょ粦瀹氬埌/feeds/鐨勮鍥撅紝Django浣跨敤URL鐨勫叾瀹冮儴鍒(鍦/feeds/涔嬪悗鐨勪换浣曚笢瑗)鏉ュ喅瀹氳緭鍑 鍝釜feed
To create a feed, youll write a Feed class and point to it in your URLconf (see Chapters 3 and 8 for more about URLconfs).
瑕佸垱寤轰竴涓猣eed, 鎮ㄥ皢鍒涘缓涓涓 Feed 绫, 骞跺湪鎮ㄧ殑 URLconf 涓寚鍚戝畠. ( 鏌ョ湅绗3绔犲拰绗8绔, 鍙互鑾峰彇鏇村鏈夊叧URLconfs鐨勬洿澶氫俊鎭 )
To activate syndication feeds on your Django site, add this URLconf:
涓轰簡鍦ㄦ偍鐨凞jango绔欑偣涓縺娲籹yndication feeds, 娣诲姞濡備笅鐨 URLconf:
(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds} ),
This line tells Django to use the RSS framework to handle all URLs starting with "feeds/" . (You can change that "feeds/" prefix to fit your own needs.)
杩欎竴琛屽憡璇塂jango浣跨敤RSS妗嗘灦澶勭悊鎵鏈夌殑浠 "feeds/" 寮澶寸殑URL. ( 浣犲彲浠ヤ慨鏀 "feeds/" 鍓嶇紑浠ユ弧瓒虫偍鑷繁鐨勮姹. )
This URLconf line has an extra argument: {'feed_dict': feeds} . Use this extra argument to pass the syndication framework the feeds that should be published under that URL.
URLConf閲屾湁涓琛屽弬鏁帮細``{‘feed_dict’: feeds}``锛岃繖涓弬鏁板彲浠ユ妸瀵瑰簲URL闇瑕佸彂甯冪殑feed鍐呭浼犻掔粰 syndication framework
Specifically, feed_dict should be a dictionary that maps a feeds slug (short URL label) to its Feed class. You can define the feed_dict in the URLconf itself. Heres a full example URLconf:
鐗瑰埆鐨勶紝feed_dict搴旇鏄竴涓槧灏刦eed鐨剆lug(绠鐭璘RL鏍囩)鍒板畠鐨凢eed绫荤殑瀛楀吀 浣犲彲浠ュ湪URL閰嶇疆鏈韩閲屽畾涔塮eed_dict锛岃繖閲屾槸涓涓畬鏁寸殑渚嬪瓙
from django.conf.urls.defaults import * from myproject.feeds import LatestEntries, LatestEntriesByCategory feeds = { 'latest': LatestEntries, 'categories': LatestEntriesByCategory, } urlpatterns = patterns('', # ... (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), # ... )
The preceding example registers two feeds:
鍓嶉潰鐨勪緥瀛愭敞鍐屼簡涓や釜feed:
The feed represented by LatestEntries will live at feeds/latest/ .
LatestEntries``琛ㄧず鐨勫唴瀹瑰皢瀵瑰簲鍒癭`feeds/latest/ .
The feed represented by LatestEntriesByCategory will live at feeds/categories/ .
LatestEntriesByCategory``鐨勫唴瀹瑰皢瀵瑰簲鍒 ``feeds/categories/ .
Once thats set up, youll need to define the Feed classes themselves.
浠ヤ笂鐨勮瀹氬畬鎴愪箣鍚庯紝鎺ヤ笅鏉ラ渶瑕佽嚜宸卞畾涔 Feed 绫
A Feed class is a simple Python class that represents a syndication feed. A feed can be simple (e.g., a site news feed, or a basic feed displaying the latest entries of a blog) or more complex (e.g., a feed displaying all the blog entries in a particular category, where the category is variable).
涓涓 Feed 绫绘槸涓涓畝鍗曠殑python绫伙紝鐢ㄦ潵琛ㄧず涓涓猻yndication feed. 涓涓猣eed鍙兘鏄畝鍗曠殑 (渚嬪涓涓珯鐐规柊闂籪eed锛屾垨鑰呮渶鍩烘湰鐨勶紝鏄剧ず涓涓猙log鐨勬渶鏂版潯鐩)锛屼篃鍙兘鏇村姞澶嶆潅(渚嬪涓涓樉绀篵log鏌愪竴绫诲埆涓嬫墍鏈夋潯鐩殑feed銆傝繖閲岀被鍒 category 鏄釜鍙橀噺).
Feed classes must subclass django.contrib.syndication.feeds.Feed . They can live anywhere in your code tree.
Feed绫诲繀椤荤户鎵縟jango.contrib.syndication.feeds.Feed锛屽畠浠彲浠ュ湪浣犵殑浠g爜鏍戠殑浠讳綍浣嶇疆
This simple example, taken from chicagocrime.org, describes a feed of the latest five news items:
渚嬪瓙鏉ヨ嚜浜巆hicagocrime.org锛屾弿杩版渶杩5椤规柊闂绘潯鐩殑feed:
from django.contrib.syndication.feeds import Feed from chicagocrime.models import NewsItem class LatestEntries(Feed): title = "Chicagocrime.org site news" link = "/sitenews/" description = "Updates on changes and additions to chicagocrime.org." def items(self): return NewsItem.objects.order_by('-pub_date')[:5]
The important things to notice here are as follows:
瑕佹敞鎰忕殑閲嶈鐨勪簨鎯呭涓嬫墍绀:
The class subclasses django.contrib.syndication.feeds.Feed .
瀛愮被 django.contrib.syndication.feeds.Feed .
title , link , and description correspond to the standard RSS <title> , <link> , and <description> elements, respectively.
title , link , 鍜 description 瀵瑰簲涓涓爣鍑 RSS 閲岀殑 <title> , <link> , 鍜 <description> 鏍囩.
items() is simply a method that returns a list of objects that should be included in the feed as <item> elements. Although this example returns NewsItem objects using Djangos database API, items() doesnt have to return model instances.
items() 鏄竴涓柟娉曪紝杩斿洖涓涓敤浠ュ寘鍚湪鍖呭惈鍦╢eed鐨 <item> 鍏冪礌閲岀殑 list 铏界劧渚嬪瓙閲岀敤Djangos database API杩斿洖鐨 NewsItem 瀵硅薄, items() 涓嶄竴瀹氬繀椤昏繑鍥 model鐨勫疄渚
You do get a few bits of functionality for free by using Django models, but items() can return any type of object you want.
浣犲彲浠ュ埄鐢 Django models鍏嶈垂瀹炵幇涓瀹氬姛鑳斤紝浣嗘槸 items() 鍙互杩斿洖浣犳兂瑕佺殑浠绘剰绫诲瀷鐨勫璞.
Theres just one more step. In an RSS feed, each <item> has a <title> , <link> , and <description> . We need to tell the framework what data to put into those elements.
杩樻湁涓涓楠わ紝鍦ㄤ竴涓猂SS feed閲岋紝姣忎釜(item)鏈変竴涓(title)锛(link)鍜(description)锛屾垜浠渶瑕佸憡璇夋鏋 鎶婃暟鎹斁鍒拌繖浜涘厓绱犱腑
To specify the contents of <title> and <description> , create Django templates (see Chapter 4) called feeds/latest_title.html and feeds/latest_description.html , where latest is the slug specified in the URLconf for the given feed. Note that the .html extension is required.
濡傛灉瑕佹寚瀹 <title> 鍜 <description> 锛屽彲浠ュ缓绔嬩竴涓狣jango妯℃澘锛堣Chapter 4锛夊悕瀛楀彨 feeds/latest_title.html 鍜 feeds/latest_description.html 锛屽悗鑰呮槸URLConf閲屼负瀵瑰簲feed鎸囧畾鐨 slug 銆傛敞鎰 .html 鍚庣紑鏄繀椤荤殑銆
The RSS system renders that template for each item, passing it two template context variables:
RSS绯荤粺妯℃澘娓叉煋姣忎竴涓潯鐩紝闇瑕佺粰浼犻2涓弬鏁扮粰妯℃澘涓婁笅鏂囧彉閲忥細
obj : The current object (one of whichever objects you returned in items() ).
obj : 褰撳墠瀵硅薄 ( 杩斿洖鍒 items() 浠绘剰瀵硅薄涔嬩竴 )銆
site : A django.models.core.sites.Site object representing the current site. This is useful for {{ site.domain }} or {{ site.name }} .
site : 涓涓〃绀哄綋鍓嶇珯鐐圭殑 django.models.core.sites.Site 瀵硅薄銆 杩欏浜 {{ site.domain }} 鎴栬 {{ site.name }} 寰堟湁鐢ㄣ
If you dont create a template for either the title or description, the framework will use the template "{{ obj }}" by default that is, the normal string representation of the object.
濡傛灉浣犲湪鍒涘缓妯℃澘鐨勬椂鍊欙紝娌℃湁鎸囨槑鏍囬鎴栬呮弿杩颁俊鎭紝妗嗘灦浼氶粯璁や娇鐢 "{{ obj }}" 锛屽璞$殑瀛楃涓茶〃绀恒
You can also change the names of these two templates by specifying title_template and description_template as attributes of your Feed class.
浣犱篃鍙互閫氳繃淇敼 Feed 绫讳腑鐨勪袱涓睘鎬 title_template 鍜 description_template 鏉ユ敼鍙樿繖涓や釜妯℃澘鐨勫悕瀛椼
To specify the contents of <link> , you have two options. For each item in items() , Django first tries executing a get_absolute_url() method on that object. If that method doesnt exist, it tries calling a method item_link() in the Feed class, passing it a single parameter, item , which is the object itself.
浣犳湁涓ょ鏂规硶鏉ユ寚瀹 <link> 鐨勫唴瀹广 Django 棣栧厛鎵ц items() 涓瘡涓椤圭殑 get_absolute_url() 鏂规硶銆 濡傛灉璇ユ柟娉曚笉瀛樺湪锛屽氨浼氬皾璇曟墽琛 Feed 绫讳腑鐨 item_link() 鏂规硶锛屽苟灏嗚嚜韬綔涓 item 鍙傛暟浼犻掕繘鍘汇
Both get_absolute_url() and item_link() should return the items URL as a normal Python string.
get_absolute_url() 鍜 item_link() 閮藉簲璇ヤ互Python瀛楃涓插舰寮忚繑鍥濽RL銆
For the previous LatestEntries example, we could have very simple feed templates. latest_title.html contains:
瀵逛簬鍓嶉潰鎻愬埌鐨 LatestEntries 渚嬪瓙锛屾垜浠彲浠ュ疄鐜颁竴涓畝鍗曠殑feed妯℃澘銆 latest_title.html 鍖呮嫭锛
{{ obj.title }}
and latest_description.html contains:
骞朵笖 latest_description.html 鍖呭惈:
{{ obj.description }}
Its almost too easy
杩欑湡鏄 澶 绠鍗曚簡锛
The framework also supports more complex feeds, via parameters.
妗嗘灦閫氳繃鍙傛暟鏀寔鏇村姞澶嶆潅鐨刦eeds銆
For example, chicagocrime.org offers an RSS feed of recent crimes for every police beat in Chicago. It would be silly to create a separate Feed class for each police beat; that would violate the Dont Repeat Yourself (DRY) principle and would couple data to programming logic.
涓句釜渚嬪瓙锛宑hicagocrime.org鎻愪緵浜嗕竴涓猂SS婧愪互璺熻釜姣忎竴鐗囧尯鍩熺殑鐘姜杩戝喌銆傚鏋滀负姣忎竴涓崟鐙殑鍖哄煙寤虹珛涓涓 Feed 绫诲氨鏄惧緱寰堜笉鏄庢櫤銆傝繖鏍峰仛灏辫繚鍙嶄簡DRY鍘熷垯浜嗭紝绋嬪簭閫昏緫涔熶細鍜屾暟鎹﹀悎鍦ㄤ竴璧枫
Instead, the syndication framework lets you make generic feeds that return items based on information in the feeds URL.
鍙栬屼唬涔嬬殑鏂规硶鏄紝浣跨敤鑱氬悎妗嗘灦鏉ヤ骇鐢熶竴涓氱敤鐨勬簮锛屼娇鍏跺彲浠ユ牴鎹甪eeds URL杩斿洖鐩稿簲鐨勪俊鎭
On chicagocrime.org, the police-beat feeds are accessible via URLs like this:
鍦╟hicagocrime杩欎釜渚嬪瓙涓紝鍖哄煙淇℃伅鍙互閫氳繃杩欐牱鐨刄RL鏂瑰紡鏉ヨ闂:
http://www.chicagocrime.org/rss/beats/0613/ : Returns recent crimes for beat 0613
http://www.chicagocrime.org/rss/beats/0613/ 锛氳繑鍥0613鍙峰湴鍖虹殑鐘姜鏁版嵁
http://www.chicagocrime.org/rss/beats/1424/ : Returns recent crimes for beat 1424
http://www.chicagocrime.org/rss/beats/1424/ 锛氳繑鍥1424鍙峰湴鍖虹殑鐘姜鏁版嵁
The slug here is "beats" . The syndication framework sees the extra URL bits after the slug 0613 and 1424 and gives you a hook to tell it what those URL bits mean and how they should influence which items get published in the feed.
鍥哄畾鐨勯偅涓閮ㄥ垎鏄 "beats" 锛堝尯鍩燂級銆傝仛鍚堟鏋剁湅鍒颁簡鍚庨潰鐨勪笉鍚屼箣澶 0613 鍜 1424 锛屽畠浼氭彁渚涚粰浣犱竴涓挬瀛愬嚱鏁版潵鎻忚堪杩欎簺URL鐨勬剰涔夛紝浠ュ強浼氬feed涓殑椤逛骇鐢熺殑褰卞搷銆
An example makes this clear. Heres the code for these beat-specific feeds:
涓句釜渚嬪瓙浼氭緞娓呬竴鍒囥備笅闈㈡槸姣忎釜鍦板尯鐗瑰畾鐨刦eeds锛
from django.core.exceptions import ObjectDoesNotExist class BeatFeed(Feed): def get_object(self, bits): # In case of "/rss/beats/0613/foo/bar/baz/", or other such # clutter, check that bits has only one member. if len(bits) != 1: raise ObjectDoesNotExist return Beat.objects.get(beat__exact=bits[0]) def title(self, obj): return "Chicagocrime.org: Crimes for beat %s" % obj.beat def link(self, obj): return obj.get_absolute_url() def description(self, obj): return "Crimes recently reported in police beat %s" % obj.beat def items(self, obj): crimes = Crime.objects.filter(beat__id__exact=obj.id) return crimes.order_by('-crime_date')[:30]
Heres the basic algorithm the RSS framework, given this class and a request to the URL /rss/beats/0613/ :
浠ヤ笅鏄疪SS妗嗘灦鐨勫熀鏈畻娉曪紝鎴戜滑鍋囪閫氳繃URL /rss/beats/0613/ 鏉ヨ闂繖涓被锛
The framework gets the URL /rss/beats/0613/ and notices theres an extra bit of URL after the slug. It splits that remaining string by the slash character ("/" ) and calls the Feed classs get_object() method, passing it the bits.
妗嗘灦鑾峰緱浜哢RL /rss/beats/0613/ 骞朵笖娉ㄦ剰鍒癠RL涓殑slug閮ㄥ垎鍚庨潰鍚湁鏇村鐨勪俊鎭傚畠灏嗘枩鏉("/" )浣滀负鍒嗛殧绗︼紝鎶婂墿浣欑殑瀛楃涓插垎鍓插紑浣滀负鍙傛暟锛岃皟鐢 Feed 绫荤殑 get_object() 鏂规硶銆
In this case, bits is ['0613'] . For a request to /rss/beats/0613/foo/bar/ , bits would be ['0613', 'foo', 'bar'] .
鍦ㄨ繖涓緥瀛愪腑锛屾坊鍔犵殑淇℃伅鏄 ['0613'] 銆傚浜 /rss/beats/0613/foo/bar/ 鐨勪竴涓猆RL璇锋眰锛 杩欎簺淇℃伅灏辨槸 ['0613', 'foo', 'bar'] 銆
get_object() is responsible for retrieving the given beat, from the given bits .
get_object() 灏辨牴鎹粰瀹氱殑 bits 鍊兼潵杩斿洖鍖哄煙淇℃伅銆
In this case, it uses the Django database API to retrieve the beat. Note that get_object() should raise django.core.exceptions.ObjectDoesNotExist if given invalid parameters. Theres no try /except around the Beat.objects.get() call, because its not necessary. That function raises Beat.DoesNotExist on failure, and Beat.DoesNotExist is a subclass of ObjectDoesNotExist . Raising ObjectDoesNotExist in get_object() tells Django to produce a 404 error for that request.
鍦ㄨ繖涓緥瀛愪腑锛屽畠浣跨敤浜咲jango鐨勬暟鎹簱API鏉ヨ幏鍙栦俊鎭傛敞鎰忓埌濡傛灉缁欏畾鐨勫弬鏁颁笉鍚堟硶锛 get_object() 浼氭姏鍑 django.core.exceptions.ObjectDoesNotExist 寮傚父銆傚湪 Beat.objects.get() 璋冪敤涓篃娌℃湁鍑虹幇 try /except 浠g爜鍧椼傚嚱鏁板湪鍑洪敊鏃舵姏鍑 Beat.DoesNotExist 寮傚父锛岃 Beat.DoesNotExist 鏄 ObjectDoesNotExist 寮傚父鐨勪竴涓瓙绫诲瀷銆 鑰屽湪 get_object()
涓姏鍑 ObjectDoesNotExist 寮傚父鍙堜細浣垮緱Django寮曞彂404閿欒銆
To generate the feeds <title> , <link> , and <description> , Django uses the title() , link() , and description() methods. In the previous example, they were simple string class attributes, but this example illustrates that they can be either strings or methods. For each of title , link , and description , Django follows this algorithm:
涓轰骇鐢 <title> 锛 <link> 锛 鍜 <description> 鐨刦eeds锛 Django浣跨敤 title() , link() , 鍜 description() 鏂规硶銆 鍦ㄤ笂闈㈢殑渚嬪瓙涓紝瀹冧滑閮芥槸绠鍗曠殑瀛楃涓茬被鍨嬬殑绫诲睘鎬э紝鑰岃繖涓緥瀛愯〃鏄庯紝瀹冧滑鏃㈠彲浠ユ槸瀛楃涓诧紝 涔熷彲浠ユ槸 鏂规硶銆傚浜庢瘡涓涓 title 锛 link 鍜 description 鐨勭粍鍚堬紝Django浣跨敤浠ヤ笅鐨勭畻娉曪細
It tries to call a method, passing the obj argument, where obj is the object returned by get_object() .
璇曞浘璋冪敤涓涓嚱鏁帮紝骞朵笖浠 get_object() 杩斿洖鐨勫璞′綔涓哄弬鏁颁紶閫掔粰 obj 鍙傛暟銆
Failing that, it tries to call a method with no arguments.
濡傛灉娌℃湁鎴愬姛锛屽垯涓嶅甫鍙傛暟璋冪敤涓涓柟娉曘
Failing that, it uses the class attribute.
杩樹笉鎴愬姛锛屽垯浣跨敤绫诲睘鎬с
Finally, note that items() in this example also takes the obj argument. The algorithm for items is the same as described in the previous step first, it tries items(obj) , then items() , and then finally an items class attribute (which should be a list).
鏈鍚庯紝鍊煎緱娉ㄦ剰鐨勬槸锛岃繖涓緥瀛愪腑鐨 items() 浣跨敤 obj 鍙傛暟銆傚浜 items 鐨勭畻娉曞氨濡傚悓涓婇潰绗竴姝ユ墍鎻忚堪鐨勯偅鏍凤紝棣栧厛灏濊瘯 items(obj) 锛 鐒跺悗鏄 items() 锛屾渶鍚庢槸 items 绫诲睘鎬э紙蹇呴』鏄竴涓垪琛級銆
Full documentation of all the methods and attributes of the Feed classes is always available from the official Django documentation (http://www.djangoproject.com/documentation/0.96/syndication_feeds/).
Feed 绫绘墍鏈夋柟娉曞拰灞炴х殑瀹屾暣鏂囨。锛岃鍙傝冨畼鏂圭殑Django鏂囨。 (http://www.djangoproject.com/documentation/0.96/syndication_feeds/) 銆
By default, the syndication framework produces RSS 2.0. To change that, add a feed_type attribute to your Feed class:
榛樿鎯呭喌涓, 鑱氬悎妗嗘灦鐢熸垚RSS 2.0. 瑕佹敼鍙樿繖鏍风殑鎯呭喌, 鍦 Feed 绫讳腑娣诲姞涓涓 feed_type 灞炴.
from django.utils.feedgenerator import Atom1Feed class MyFeed(Feed): feed_type = Atom1Feed
Note that you set feed_type to a class object, not an instance. Currently available feed types are shown in Table 11-1.
娉ㄦ剰浣犳妸 feed_type 璧嬪兼垚涓涓被瀵硅薄锛岃屼笉鏄被瀹炰緥銆傜洰鍓嶅悎娉曠殑Feed绫诲瀷濡傝〃11-1鎵绀恒
Feed Class | Format |
---|---|
django.utils.feedgenerator.Rss201rev2Feed | RSS 2.01 (default) |
django.utils.feedgenerator.RssUserland091Feed | RSS 0.91 |
django.utils.feedgenerator.Atom1Feed | Atom 1.0 |
Feed 绫 | 绫诲瀷 |
---|---|
django.utils.feedgenerator.Rss201rev2Feed | RSS 2.01 (default) |
django.utils.feedgenerator.RssUserland091Feed | RSS 0.91 |
django.utils.feedgenerator.Atom1Feed | Atom 1.0 |
To specify enclosures (i.e., media resources associated with a feed item such as MP3 podcast feeds), use the item_enclosure_url , item_enclosure_length , and item_enclosure_mime_type hooks, for example:
涓轰簡鎸囧畾闂寘锛堜緥濡傦紝涓巉eed椤规瘮鏂硅MP3 feeds鐩稿叧鑱旂殑濯掍綋璧勬簮淇℃伅锛夛紝浣跨敤 item_enclosure_url 锛 item_enclosure_length 锛 浠ュ強 item_enclosure_mime_type 锛屾瘮濡
from myproject.models import Song class MyFeedWithEnclosures(Feed): title = "Example feed with enclosures" link = "/feeds/example-with-enclosures/" def items(self): return Song.objects.all()[:30] def item_enclosure_url(self, item): return item.song_url def item_enclosure_length(self, item): return item.song_length item_enclosure_mime_type = "audio/mpeg"
This assumes, of course, that youve created a Song object with song_url and song_length (i.e., the size in bytes) fields.
褰撶劧锛屼綘棣栧厛瑕佸垱寤轰竴涓寘鍚湁 song_url 鍜 song_length 锛堟瘮濡傛寜鐓у瓧鑺傝绠楃殑闀垮害锛夊煙鐨 Song 瀵硅薄銆
Feeds created by the syndication framework automatically include the appropriate <language> tag (RSS 2.0) or xml:lang attribute (Atom). This comes directly from your LANGUAGE_CODE setting.
鑱氬悎妗嗘灦鑷姩鍒涘缓鐨凢eed鍖呭惈閫傚綋鐨 <language> 鏍囩(RSS 2.0) 鎴 xml:lang 灞炴(Atom). 浠栫洿鎺ユ潵鑷簬鎮ㄧ殑 LANGUAGE_CODE 璁剧疆.
The link method/attribute can return either an absolute URL (e.g., "/blog/" ) or a URL with the fully qualified domain and protocol (e.g., "http://www.example.com/blog/" ). If link doesnt return the domain, the syndication framework will insert the domain of the current site, according to your SITE_ID setting.
link 鏂规硶/灞炴у彲浠ヤ互缁濆URL鐨勫舰寮忥紙渚嬪锛 "/blog/" 锛夋垨鑰呮寚瀹氬崗璁拰鍩熷悕鐨刄RL鐨勫舰寮忚繑鍥烇紙渚嬪 "http://www.example.com/blog/" 锛夈傚鏋 link 娌℃湁杩斿洖鍩熷悕锛岃仛鍚堟鏋朵細鏍规嵁 SITE_ID 璁剧疆锛岃嚜鍔ㄧ殑鎻掑叆褰撳墠绔欑偣鐨勫煙淇℃伅銆
Atom feeds require a <link rel="self"> that defines the feeds current location. The syndication framework populates this automatically, using the domain of the current site according to the SITE_ID setting.
Atom feeds闇瑕 <link rel="self"> 鎸囨槑feeds鐜板湪鐨勪綅缃傝仛鍚堟鏋舵牴鎹 SITE_ID 鐨勮缃紝浣跨敤绔欑偣鐨勫煙鍚嶈嚜鍔ㄥ畬鎴愯繖浜涘姛鑳姐
鍚屾椂鍙戝竷Atom and RSS
Some developers like to make available both Atom and RSS versions of their feeds. Thats easy to do with Django: just create a subclass of your feed class and set the feed_type to something different. Then update your URLconf to add the extra versions. Heres a full example:
涓浜涘紑鍙戜汉鍛樻兂 鍚屾椂 鏀寔Atom鍜孯SS銆傝繖鍦―jango涓緢瀹规槗瀹炵幇锛氬彧闇鍒涘缓涓涓綘鐨 feed 绫荤殑瀛愮被锛岀劧鍚庝慨鏀 feed_type 锛屽苟涓旀洿鏂癠RLconf鍐呭銆備笅闈㈡槸涓涓畬鏁寸殑渚嬪瓙锛
from django.contrib.syndication.feeds import Feed from chicagocrime.models import NewsItem from django.utils.feedgenerator import Atom1Feed class RssSiteNewsFeed(Feed): title = "Chicagocrime.org site news" link = "/sitenews/" description = "Updates on changes and additions to chicagocrime.org." def items(self): return NewsItem.objects.order_by('-pub_date')[:5] class AtomSiteNewsFeed(RssSiteNewsFeed): feed_type = Atom1Feed
And heres the accompanying URLconf:
杩欐槸涓庝箣鐩稿搴旈偅涓殑URLconf锛
from django.conf.urls.defaults import * from myproject.feeds import RssSiteNewsFeed, AtomSiteNewsFeed feeds = { 'rss': RssSiteNewsFeed, 'atom': AtomSiteNewsFeed, } urlpatterns = patterns('', # ... (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), # ... )
A sitemap is an XML file on your Web site that tells search engine indexers how frequently your pages change and how important certain pages are in relation to other pages on your site. This information helps search engines index your site.
sitemap 鏄綘鏈嶅姟鍣ㄤ笂鐨勪竴涓猉ML鏂囦欢锛屽畠鍛婅瘔鎼滅储寮曟搸浣犵殑椤甸潰鐨勬洿鏂伴鐜囧拰鏌愪簺椤甸潰鐩稿浜庡叾瀹冮〉闈㈢殑閲嶈鎬с傝繖涓俊鎭細甯姪鎼滅储寮曟搸绱㈠紩浣犵殑缃戠珯銆
For example, heres a piece of the sitemap for Djangos Web site (http://www.djangoproject.com/sitemap.xml):
渚嬪锛岃繖鏄 Django 缃戠珯(http://www.djangoproject.com/sitemap.xml)sitemap鐨勪竴閮ㄥ垎锛
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>http://www.djangoproject.com/documentation/</loc> <changefreq>weekly</changefreq> <priority>0.5</priority> </url> <url> <loc>http://www.djangoproject.com/documentation/0_90/</loc> <changefreq>never</changefreq> <priority>0.1</priority> </url> ... </urlset>
For more on sitemaps, see http://www.sitemaps.org/.
闇瑕佷簡瑙f洿澶氭湁鍏 sitemaps 鐨勪俊鎭, 璇峰弬瑙 http://www.sitemaps.org/.
The Django sitemap framework automates the creation of this XML file by letting you express this information in Python code. To create a sitemap, you just need to write a Sitemap class and point to it in your URLconf.
Django sitemap 妗嗘灦鍏佽浣犵敤 Python 浠g爜鏉ヨ〃杩拌繖浜涗俊鎭紝浠庤岃嚜鍔ㄥ垱寤鸿繖涓猉ML鏂囦欢銆傝鍒涘缓涓涓 sitemap锛屼綘鍙渶瑕佸啓涓涓 Sitemap 绫荤劧鍚庨厤缃綘鐨刄RLconf鎸囧悜瀹冦
To install the sitemap application, follow these steps:
瑕佸畨瑁 sitemap 搴旂敤绋嬪簭, 鎸変笅闈㈢殑姝ラ杩涜:
Add 'django.contrib.sitemaps' to your INSTALLED_APPS setting.
灏 'django.contrib.sitemaps' 娣诲姞鍒版偍鐨 INSTALLED_APPS 璁剧疆涓.
Make sure 'django.template.loaders.app_directories.load_template_source' is in your TEMPLATE_LOADERS setting. Its in there by default, so youll need to change this only if youve changed that setting.
纭繚 'django.template.loaders.app_directories.load_template_source' 鍦ㄦ偍鐨 TEMPLATE_LOADERS 璁剧疆涓傞粯璁ゆ儏鍐典笅瀹冨湪閭i噷, 鎵浠, 濡傛灉浣犲凡缁忔敼鍙樹簡閭d釜璁剧疆鐨勮瘽, 鍙渶瑕佹敼鍥炴潵鍗冲彲銆
Make sure youve installed the sites framework (see Chapter 14).
纭畾鎮ㄥ凡缁忓畨瑁呬簡 sites 妗嗘灦 (鍙傝绗14绔).
Note
澶囨敞
The sitemap application doesnt install any database tables. The only reason it needs to go into INSTALLED_APPS is so the load_template_source template loader can find the default templates.
sitemap 搴旂敤绋嬪簭娌℃湁瀹夎浠讳綍鏁版嵁搴撹〃. 瀹冮渶瑕佸姞鍏ュ埌 INSTALLED_APPS 涓殑鍞竴鍘熷洜鏄: 杩欐牱 load_template_source 妯℃澘鍔犺浇鍣ㄥ彲浠ユ壘鍒伴粯璁ょ殑妯℃澘.
To activate sitemap generation on your Django site, add this line to your URLconf:
瑕佸湪鎮ㄧ殑Django绔欑偣涓縺娲籹itemap鐢熸垚, 璇峰湪鎮ㄧ殑 URLconf 涓坊鍔犺繖涓琛:
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
This line tells Django to build a sitemap when a client accesses /sitemap.xml .
杩欎竴琛屽憡璇 Django, 褰撳鎴疯闂 /sitemap.xml 鐨勬椂鍊, 鏋勫缓涓涓 sitemap.
The name of the sitemap file is not important, but the location is. Search engines will only index links in your sitemap for the current URL level and below. For instance, if sitemap.xml lives in your root directory, it may reference any URL in your site. However, if your sitemap lives at /content/sitemap.xml , it may only reference URLs that begin with /content/ .
sitemap鏂囦欢鐨勫悕瀛楁棤鍏崇揣瑕侊紝浣嗘槸瀹冨湪鏈嶅姟鍣ㄤ笂鐨勪綅缃嵈寰堥噸瑕併傛悳绱㈠紩鎿庡彧绱㈠紩浣犵殑sitemap涓綋鍓峌RL绾у埆鍙婂叾浠ヤ笅绾у埆鐨勯摼鎺ャ傜敤涓涓疄渚嬫潵璇达紝濡傛灉 sitemap.xml 浣嶄簬浣犵殑鏍圭洰褰曪紝閭d箞瀹冨皢寮曠敤浠讳綍鐨刄RL銆傜劧鑰岋紝濡傛灉浣犵殑sitemap浣嶄簬 /content/sitemap.xml 锛岄偅涔堝畠鍙紩鐢ㄤ互 /content/ 鎵撳ご鐨刄RL銆
The sitemap view takes an extra, required argument: {'sitemaps': sitemaps} . sitemaps should be a dictionary that maps a short section label (e.g., blog or news ) to its Sitemap class (e.g., BlogSitemap or NewsSitemap ). It may also map to an instance of a Sitemap class (e.g., BlogSitemap(some_var) ).
sitemap瑙嗗浘闇瑕佷竴涓澶栫殑蹇呴』鐨勫弬鏁帮細 {'sitemaps': sitemaps} 銆 sitemaps 搴旇鏄竴涓瓧鍏革紝瀹冩妸涓涓煭鐨勫潡鏍囩(渚嬪, blog 鎴 news )鏄犲皠鍒板畠鐨 Sitemap 绫(渚嬪锛 BlogSitemap 鎴 NewsSitemap )銆傚畠涔熷彲浠ユ槧灏勫埌涓涓 Sitemap 绫荤殑瀹炰緥(渚嬪锛 BlogSitemap(some_var) )銆
A Sitemap class is a simple Python class that represents a section of entries in your sitemap. For example, one Sitemap class could represent all the entries of your Weblog, while another could represent all of the events in your events calendar.
Sitemap 绫诲睍绀轰簡涓涓繘鍏ュ湴鍥剧珯鐐圭畝鍗曠殑Python绫荤墖鏂.渚嬪,涓涓 Sitemap 绫昏兘灞曠幇鎵鏈夋棩蹇楀叆鍙o紝鑰屽彟澶栦竴涓兘澶熻皟搴︽墍鏈夌殑鏃ュ巻浜嬩欢銆
In the simplest case, all these sections get lumped together into one sitemap.xml , but its also possible to use the framework to generate a sitemap index that references individual sitemap files, one per section (as described shortly).
鍦ㄦ渶绠鍗曠殑渚嬪瓙涓紝鎵鏈夐儴鍒嗗彲浠ュ叏閮ㄥ寘鍚湪涓涓 sitemap.xml 涓紝涔熷彲浠ヤ娇鐢ㄦ鏋舵潵浜х敓涓涓珯鐐瑰湴鍥撅紝涓烘瘡涓涓嫭绔嬬殑閮ㄥ垎浜х敓涓涓崟鐙殑绔欑偣鏂囦欢銆
Sitemap classes must subclass django.contrib.sitemaps.Sitemap . They can live anywhere in your code tree.
Sitemap 绫诲繀椤绘槸 django.contrib.sitemaps.Sitemap 鐨勫瓙绫. 浠栦滑鍙互瀛樺湪浜庢偍鐨勪唬鐮佹爲鐨勪换浣曞湴鏂广
For example, lets assume you have a blog system, with an Entry model, and you want your sitemap to include all the links to your individual blog entries. Heres how your Sitemap class might look:
渚嬪鍋囪浣犳湁涓涓猙log绯荤粺锛屾湁涓涓 Entry 鐨刴odel锛屽苟涓斾綘甯屾湜浣犵殑绔欑偣鍦板浘鍖呭惈鎵鏈夎繛鍒颁綘鐨刡log鍏ュ彛鐨勮秴閾炬帴銆備綘鐨 Sitemap 绫诲緢鍙兘鏄繖鏍风殑锛
from django.contrib.sitemaps import Sitemap from mysite.blog.models import Entry class BlogSitemap(Sitemap): changefreq = "never" priority = 0.5 def items(self): return Entry.objects.filter(is_draft=False) def lastmod(self, obj): return obj.pub_date
Declaring a Sitemap should look very similar to declaring a Feed ; thats by design.
澹版槑涓涓 Sitemap 鍜屽0鏄庝竴涓 Feed 鐪嬭捣鏉ュ緢绫讳技锛涜繖閮芥槸棰勫厛璁捐濂界殑銆
Like Feed classes, Sitemap members can be either methods or attributes. See the steps in the earlier A Complex Example section for more about how this works.
濡傚悓 Feed 绫讳竴鏍凤紝 Sitemap 鎴愬憳涔熸棦鍙互鏄柟娉曪紝涔熷彲浠ユ槸灞炴с傛兂瑕佺煡閬撴洿璇︾粏鐨勫唴瀹癸紝璇峰弬瑙佷笂鏂 銆婁竴涓鏉傜殑渚嬪瓙銆嬬珷鑺傘
A Sitemap class can define the following methods/attributes:
涓涓 Sitemap 绫诲彲浠ュ畾涔夊涓 鏂规硶/灞炴:
items (required ): Provides list of objects. The framework doesnt care what type of objects they are; all that matters is that these objects get passed to the location() , lastmod() , changefreq() , and priority() methods.
items (蹇呴渶 )锛氭彁渚涘璞″垪琛ㄣ傛鏋跺苟涓嶅叧蹇冨璞$殑 绫诲瀷 锛涘敮涓鍏冲績鐨勬槸杩欎簺瀵硅薄浼氫紶閫掔粰 location() 锛 lastmod() 锛 changefreq() 锛屽拰 priority() 鏂规硶銆
location (optional): Gives the absolute URL for a given object. Here, absolute URL means a URL that doesnt include the protocol or domain. Here are some examples:
location 锛堝彲閫夛級锛氱粰瀹氬璞$殑缁濆URL銆傜粷瀵筓RL涓嶅寘鍚崗璁悕绉板拰鍩熷悕銆備笅闈㈡槸涓浜涗緥瀛愶細
Good: '/foo/bar/'
濂界殑: '/foo/bar/'
Bad: 'example.com/foo/bar/'
宸殑: 'example.com/foo/bar/'
Bad: 'http://example.com/foo/bar/'
宸殑: 'http://example.com/foo/bar/'
If location isnt provided, the framework will call the get_absolute_url() method on each object as returned by items() .
濡傛灉娌℃湁鎻愪緵 location , 妗嗘灦灏嗕細鍦ㄦ瘡涓 items() 杩斿洖鐨勫璞′笂璋冪敤 get_absolute_url() 鏂规硶.
lastmod (optional): The objects last modification date, as a Python datetime object.
lastmod (鍙): 瀵硅薄鐨勬渶鍚庝慨鏀规棩鏈, 浣滀负涓涓狿ython datetime 瀵硅薄.
changefreq (optional): How often the object changes. Possible values (as given by the Sitemaps specification) are as follows:
changefreq 锛堝彲閫夛級锛氬璞″彉鏇寸殑棰戠巼銆傚彲閫夌殑鍊煎涓嬶紙璇﹁Sitemaps鏂囨。锛夛細
'always'
'always'
'hourly'
'hourly'
'daily'
'daily'
'weekly'
'weekly'
'monthly'
'monthly'
'yearly'
'yearly'
'never'
'never'
priority (optional): A suggested indexing priority between 0.0 and 1.0 . The default priority of a page is 0.5 ; see the http://sitemaps.org documentation for more about how priority works.
priority 锛堝彲閫夛級锛氬彇鍊艰寖鍥村湪 0.0 and 1.0 涔嬮棿锛岀敤鏉ヨ〃鏄庝紭鍏堢骇銆傞粯璁ゅ间负 0.5 锛涜璇﹁ http://sitemaps.org 鏂囨。銆
The sitemap framework provides a couple convenience classes for common cases. These are described in the sections that follow.
sitemap妗嗘灦鎻愪緵浜嗕竴浜涘父鐢ㄧ殑绫汇傚湪涓嬩竴閮ㄥ垎涓細鐪嬪埌銆
The django.contrib.sitemaps.FlatPageSitemap class looks at all flat pages defined for the current site and creates an entry in the sitemap. These entries include only the location attribute not lastmod , changefreq , or priority .
django.contrib.sitemaps.FlatPageSitemap 绫绘秹鍙婂埌绔欑偣涓墍鏈夌殑flat page锛屽苟鍦╯itemap涓缓绔嬩竴涓叆鍙c備絾浠呬粎鍙寘鍚 location 灞炴э紝涓嶆敮鎸 lastmod 锛 changefreq 锛屾垨鑰 priority 銆
See Chapter 14 for more about flat pages.
鍙傝绗16绔犺幏鍙栨湁鍏砯lat page鐨勬洿澶氱殑鍐呭.
The GenericSitemap class works with any generic views (see Chapter 9) you already have.
GenericSitemap 涓庢墍鏈夌殑閫氱敤瑙嗗浘涓鍚屽伐浣滐紙璇﹁绗9绔狅級銆
To use it, create an instance, passing in the same info_dict you pass to the generic views. The only requirement is that the dictionary have a queryset entry. It may also have a date_field entry that specifies a date field for objects retrieved from the queryset . This will be used for the lastmod attribute in the generated sitemap. You may also pass priority and changefreq keyword arguments to the GenericSitemap constructor to specify these attributes for all URLs.
浣犲彲浠ュ涓嬩娇鐢ㄥ畠锛屽垱寤轰竴涓疄渚嬶紝骞堕氳繃 info_dict 浼犻掔粰閫氱敤瑙嗗浘銆傚敮涓鐨勮姹傛槸瀛楀吀鍖呭惈 queryset 杩欎竴椤广備篃鍙互鐢 date_field 鏉ユ寚鏄庝粠 queryset 涓彇鍥炵殑瀵硅薄鐨勬棩鏈熷煙銆傝繖浼氳鐢ㄤ綔绔欑偣鍦板浘涓殑 lastmod 灞炴с備綘涔熷彲浠ュ悜 GenericSitemap 鐨勬瀯閫犲嚱鏁颁紶閫 priority 鍜 changefreq 鏉ユ寚瀹氭墍鏈塙RL鐨勭浉搴斿睘鎬с
Heres an example of a URLconf using both FlatPageSitemap and GenericSiteMap (with the hypothetical Entry object from earlier):
涓嬮潰鏄竴涓娇鐢 FlatPageSitemap and GenericSiteMap 锛堝寘鎷墠闈㈡墍鍋囧畾鐨 Entry 瀵硅薄锛夌殑URLconf锛
from django.conf.urls.defaults import * from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap from mysite.blog.models import Entry info_dict = { 'queryset': Entry.objects.all(), 'date_field': 'pub_date', } sitemaps = { 'flatpages': FlatPageSitemap, 'blog': GenericSitemap(info_dict, priority=0.6), } urlpatterns = patterns('', # some generic view using info_dict # ... # the sitemap (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}) )
The sitemap framework also has the ability to create a sitemap index that references individual sitemap files, one per each section defined in your sitemaps dictionary. The only differences in usage are as follows:
sitemap妗嗘灦鍚屾牱鍙互鏍规嵁 sitemaps 瀛楀吀涓畾涔夌殑鍗曠嫭鐨剆itemap鏂囦欢鏉ュ缓绔嬬储寮曘傜敤娉曞尯鍒涓嬶細
You use two views in your URLconf: django.contrib.sitemaps.views.index and django.contrib.sitemaps.views.sitemap .
鎮ㄥ湪鎮ㄧ殑URLconf 涓娇鐢ㄤ簡涓や釜瑙嗗浘: django.contrib.sitemaps.views.index 鍜 django.contrib.sitemaps.views.sitemap .
The django.contrib.sitemaps.views.sitemap view should take a section keyword argument.
django.contrib.sitemaps.views.sitemap 瑙嗗浘闇瑕佸甫涓涓 section 鍏抽敭瀛楀弬鏁.
Here is what the relevant URLconf lines would look like for the previous example:
杩欓噷鏄墠闈㈢殑渚嬪瓙鐨勭浉鍏崇殑 URLconf 琛岀湅璧锋潵鐨勬牱瀛:
(r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}), (r'^sitemap-(?P<section>.+).xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
This will automatically generate a sitemap.xml file that references both sitemap-flatpages.xml and sitemap-blog.xml . The Sitemap classes and the sitemaps dictionary dont change at all.
杩欏皢鑷姩鐢熸垚涓涓 sitemap.xml 鏂囦欢, 瀹冨悓鏃跺紩鐢 sitemap-flatpages.xml 鍜 sitemap-blog.xml . Sitemap 绫诲拰 sitemaps 鐩綍鏍规湰娌℃湁鏇存敼.
You may want to ping Google when your sitemap changes, to let it know to reindex your site. The framework provides a function to do just that: django.contrib.sitemaps.ping_google() .
褰撲綘鐨剆itemap鍙樺寲鐨勬椂鍊欙紝浣犱細鎯抽氱煡Google锛屼互渚胯瀹冪煡閬撳浣犵殑绔欑偣杩涜閲嶆柊绱㈠紩銆傛鏋跺氨鎻愪緵浜嗚繖鏍风殑涓涓嚱鏁帮細 django.contrib.sitemaps.ping_google() 銆
Note
澶囨敞
At the time this book was written, only Google responded to sitemap pings. However, its quite likely that Yahoo and/or MSN will soon support these pings as well.
鍦ㄦ湰涔﹀啓鎴愮殑鏃跺, 鍙湁Google鍙互鍝嶅簲sitemap鏇存柊閫氱煡銆傜劧鑰岋紝Yahoo鍜孧SN鍙兘寰堝揩涔熶細鏀寔杩欎簺閫氱煡銆
At that time, well likely change the name of ping_google() to something like ping_search_engines() , so make sure to check the latest sitemap documentation at http://www.djangoproject.com/documentation/0.96/sitemaps/.
鍒伴偅涓椂鍊欙紝鎶娾減ing_google()鈥濊繖涓悕瀛楁敼鎴愨減ing_search_engines()鈥濅細姣旇緝濂姐傛墍浠ヨ繕鏄埌http://www.djangoproject.com/documentation/0.96/sitemaps/ 鍘绘鏌ヤ竴涓嬫渶鏂扮殑绔欑偣鍦板浘鏂囨。銆
ping_google() takes an optional argument, sitemap_url , which should be the absolute URL of your sites sitemap (e.g., '/sitemap.xml' ). If this argument isnt provided, ping_google() will attempt to figure out your sitemap by performing a reverse lookup on your URLconf.
ping_google() 鏈変竴涓彲閫夌殑鍙傛暟 sitemap_url 锛屽畠搴旇鏄綘鐨勭珯鐐瑰湴鍥剧殑URL缁濆鍦板潃锛堜緥濡傦細 /sitemap.xml 锛夈傚鏋滀笉鎻愪緵璇ュ弬鏁帮紝 ping_google() 灏嗗皾璇曢氳繃鍙嶆煡浣犵殑URLconf鏉ユ壘鍒颁綘鐨勭珯鐐瑰湴鍥俱
ping_google() raises the exception django.contrib.sitemaps.SitemapNotFound if it cannot determine your sitemap URL.
濡傛灉涓嶈兘澶熺‘瀹氫綘鐨剆itemap URL, ping_google() 浼氬紩鍙 django.contrib.sitemaps.SitemapNotFound 寮傚父銆
One useful way to call ping_google() is from a models save() method:
鎴戜滑鍙互閫氳繃妯″瀷涓殑 save() 鏂规硶鏉ヨ皟鐢 ping_google() 锛
from django.contrib.sitemaps import ping_google class Entry(models.Model): # ... def save(self): super(Entry, self).save() try: ping_google() except Exception: # Bare 'except' because we could get a variety # of HTTP-related exceptions. pass
A more efficient solution, however, would be to call ping_google() from a cron script or some other scheduled task. The function makes an HTTP request to Googles servers, so you may not want to introduce that network overhead each time you call save() .
涓涓洿鏈夋晥鐨勮В鍐虫柟妗堟槸鐢 cron 鑴氭湰鎴栦换鍔¤皟搴﹁〃鏉ヨ皟鐢 ping_google() 锛岃鏂规硶浣跨敤Http鐩存帴璇锋眰Google鏈嶅姟鍣紝浠庤屽噺灏戞瘡娆¤皟鐢 save() 鏃跺崰鐢ㄧ殑缃戠粶甯﹀銆
Next, well continue to dig deeper into all the nifty built-in tools Django gives you. Chapter 12 looks at all the tools you need to provide user-customized sites: sessions, users, and authentication.
涓嬮潰, 鎴戜滑瑕佺户缁繁鍏ユ寲鎺樻墍鏈夌殑Django缁欎綘鐨勫緢濂界殑鍐呯疆宸ュ叿銆 鍦ㄧ12绔狅紝鎮ㄥ皢鐪嬪埌鎻愪緵鐢ㄦ埛鑷畾涔夌珯鐐规墍闇瑕佺殑鎵鏈夊伐鍏凤細 sessions, users 鍜宎uthentication.
Onward!
缁х画鍓嶈!
鍏充簬鏈瘎娉ㄧ郴缁
鏈珯浣跨敤涓婁笅鏂囧叧鑱旂殑璇勬敞绯荤粺鏉ユ敹闆嗗弽棣堜俊鎭備笉鍚屼簬涓鑸鏁寸珷鍋氳瘎娉ㄧ殑鍋氭硶锛 鎴戜滑鍏佽浣犲姣忎竴涓嫭绔嬬殑鈥滄枃鏈潡鈥濆仛璇勬敞銆備竴涓滄枃鏈潡鈥濈湅璧锋潵鏄繖鏍风殑锛
涓涓滄枃鏈潡鈥濇槸涓涓钀斤紝涓涓垪琛ㄩ」锛屼竴娈典唬鐮侊紝鎴栬呭叾浠栦竴灏忔鍐呭銆 浣犻変腑瀹冧細楂樹寒搴︽樉绀:
瑕佸鏂囨湰鍧楀仛璇勬敞锛屼綘鍙渶瑕佺偣鍑诲畠鏃佽竟鐨勬爣璇嗗潡:
鎴戜滑浼氫粩缁嗛槄璇绘瘡涓瘎璁猴紝濡傛灉鍙兘鐨勮瘽鎴戜滑涔熶細鎶婅瘎娉ㄨ冭檻鍒版湭鏉ョ殑鐗堟湰涓幓:
濡傛灉浣犳効鎰忎綘鐨勮瘎娉ㄨ閲囩敤锛岃纭繚鐣欎笅浣犵殑鍏ㄥ悕 (娉ㄦ剰涓嶆槸鏄电О鎴栫畝绉帮級
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.