最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

django中如何生成非HTML格式的內(nèi)容。_html/css_WEB-ITnose

來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 16:02:47
文檔

django中如何生成非HTML格式的內(nèi)容。_html/css_WEB-ITnose

django中如何生成非HTML格式的內(nèi)容。_html/css_WEB-ITnose:某些時候可能有這樣的需求,在網(wǎng)頁中點擊一個鏈接或者一個按鈕希望返回一張圖片、一個pdf文檔、一個csv文檔等而非HTML。在diango中很容易做到這些。django中的view用來接收http request并返回web response。通常情況下,返回的內(nèi)容為HTML,但其能夠返回的
推薦度:
導讀django中如何生成非HTML格式的內(nèi)容。_html/css_WEB-ITnose:某些時候可能有這樣的需求,在網(wǎng)頁中點擊一個鏈接或者一個按鈕希望返回一張圖片、一個pdf文檔、一個csv文檔等而非HTML。在diango中很容易做到這些。django中的view用來接收http request并返回web response。通常情況下,返回的內(nèi)容為HTML,但其能夠返回的

某些時候可能有這樣的需求,在網(wǎng)頁中點擊一個鏈接或者一個按鈕希望返回一張圖片、一個pdf文檔、一個csv文檔等而非HTML。在diango中很容易做到這些。django中的view用來接收http request并返回web response。通常情況下,返回的內(nèi)容為HTML,但其能夠返回的不僅僅如此,還可以是上述圖片、pdf文件等等。返回非HTML形式的內(nèi)容的關鍵在于HttpResponse這個類,尤其是mimetype這個參數(shù),通過將此參數(shù)設置為不同的值可以提示瀏覽器view返回了不同格式的內(nèi)容。比如,想要返回圖片內(nèi)容,只需讀如一張圖片,然后在HttpResponse中指明圖片的mimetype并將圖片內(nèi)容作為另一參數(shù)response給瀏覽器,瀏覽器能夠自動正確的顯示圖片內(nèi)容。

from django.http import HttpResponsedef my_image(request): image_data = open("/path/to/my/image.png", "rb").read() return HttpResponse(image_data, mimetype="image/png")
另外一個需要特別注意的的是HttpResponse對象實現(xiàn)了Python的標準“file-like-object”API,也即可以將HttpResponse當做文件使用。
例子:
生成CSV格式的內(nèi)容
import csvfrom 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
需要注意的幾點:
1.HttpResponse中mimetype指定為了'text/csv'告知瀏覽器返回的文檔是CSV文件。
2.HttpResponse設置了另外一個參數(shù)Content-Disposition其中attachment告知瀏覽器保存返回的文檔而非顯示其內(nèi)容,filename指明了返回文檔的名字,改名字可任意指定。
3.因為csv的writer方法期望一個文件類型的對象作為參數(shù),而HttpResponse實例可以當做文件使用,所以可以直接在csv模塊的writer方法中將HttpResponse作為參數(shù)。
4.writer.writerow方法負責往文件中寫入一行內(nèi)容。

上述方法是返回非HTML格式內(nèi)容的通用模式,也即:創(chuàng)建一個特定MIME Type的HttpResponse,將其傳遞給以文件為參數(shù)產(chǎn)生特定格式的文檔的方法,之后返回該response。

生成PDF格式的內(nèi)容
from reportlab.pdfgen import canvasfrom django.http import HttpResponsedef 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
流程基本同上,需要注意的幾點:
1.此處使用了 application/pdf MIME type告知瀏覽器返回的是PDF文件,而非HTML,否則瀏覽器會將其作為普通HTML內(nèi)容處理。
2.canvas.Canvas方法期望一個file-like的對象作為參數(shù),將HttpResponse傳遞給該方法。
3.使用Canvas實例的方法繪制PDF文檔,調(diào)用showPage()方法和save()方法(否則會產(chǎn)生損壞的pdf文檔)。
4.最后返回該HttpResponse實例

生成更為復雜的PDF文檔,這里使用了cStringIO庫來臨時存放PDF文件
from cStringIO import StringIOfrom reportlab.pdfgen import canvasfrom django.http import HttpResponsedef 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
其他可能的格式
實質(zhì)上,任何可以寫文件的Python庫都可與Django的HttpResponse結(jié)合用以返回特定格式的內(nèi)容,如ZIP文件、動態(tài)圖片、圖表、XLS文件等等。

最后在看一個返回xls文件的例子
from django.http import HttpResponseimport xlwtdef viewXls(request): response = HttpResponse(mimetype='application/vnd.ms-excel') response['Content-Disposition'] = 'attachment; filename=request.xls' book = xlwt.Workbook(encoding='utf8') sheet = book.add_sheet('untitled') for row, column, value in ((0,0,1),(0,1,2),(1,0,3),(1,1,4)) sheet.write(int(row),int(column),value) book.save(response) return response
流程同上,不在注釋。

另外,需要特別注意的是,這里的request必須是通過表單提交才能正確返回特定格式的內(nèi)容,若要是通過ajax方式發(fā)起的request則返回的內(nèi)容會被當做文本串處理,而不能被瀏覽器解釋為特定內(nèi)容。
比如:
$.ajax({ url:"{% url 'mycitsm.views.viewXls' %}", data:postData, type:"POST", success:function(result){ }, });//是不可以的,而要使用如下的表單提交才可以:var form = $("#xlsForm");form.attr({	action:"{% url 'mycitsm.views.returnXls' %}",	method:"POST" });form.submit();
說到這里有必要記錄一下開發(fā)過程中遇到的一個問題,也即將表單內(nèi)容序列化為字符串的問題。
有時需將表單中的所有內(nèi)容序列化為鍵值對構(gòu)成的串做為一個整體進行URL參數(shù)傳遞,而且需要對值中包含的特殊字符進行編碼。比如有如下表單:
$('form').submit(function() { alert($(this).serialize()); return false;});#可以
輸出a=1&c=3&d=4&e=5為什么第二個text類型的input的值還有checkbox類型的input的值以及submit類型的input沒有被序列化呢?這是因為如果要表單元素的值包含到序列字符串中,元素必須使用 name 屬性。而第二個text類型的input無name屬性。checkbox類型的input有一個并沒有被checked所以……。serialize()只會將”成功的控件“序列化為字符串。如果不使用按鈕來提交表單,則不對提交按鈕的值序列化,所以submit類型的input沒有被序列化。
當然除了直接對整個form序列化外還可對已選取的個別表單元素的jQuery對象序列化,如,