Django で非 HTML 形式のコンテンツを生成する方法。 _html/css_WEB-ITnose

WBOY
リリース: 2016-06-24 11:48:18
オリジナル
992 人が閲覧しました

場合によっては、Web ページ上のリンクまたはボタンをクリックして、HTML の代わりに画像、PDF ドキュメント、CSV ドキュメントなどを返す必要がある場合があります。 diango でこれを行うのは簡単です。 Django のビューは、http リクエストを受信し、Web レスポンスを返すために使用されます。通常、返されるコンテンツは HTML ですが、それだけではなく、上記の画像や PDF ファイルなどを返すこともできます。非 HTML コンテンツを返すための鍵は、HttpResponse クラス、特に mimetype パラメータにあります。このパラメータを別の値に設定すると、ブラウザ ビューに別の形式でコンテンツを返すように指示できます。たとえば、画像コンテンツを返したい場合は、画像を読み取って、HttpResponse で画像の MIME タイプを指定し、その画像コンテンツを別のパラメータとしてブラウザに応答するだけで、ブラウザは自動的かつ正確に応答することができます。画像の内容を表示します。

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")
ログイン後にコピー
もう 1 つ特別な注意が必要なのは、HttpResponse オブジェクトが Python の標準の「ファイルのようなオブジェクト」API を実装していることです。つまり、HttpResponse をファイルとして使用できます。
例:
CSV 形式でコンテンツを生成する

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. 返されるドキュメントが CSV であることをブラウザーに伝えるために、HttpResponse の mimetype は「text/csv」として指定されます。ファイル。
2.HttpResponse は、別のパラメーター Content-Disposition を設定します。ここで、添付ファイルは、コンテンツを表示する代わりに、返されたドキュメントを保存するようにブラウザーに指示し、ファイル名は返されたドキュメントの名前を指定します。名前は任意に指定できます。
3. csv の Writer メソッドはパラメータとしてファイル タイプのオブジェクトを期待しており、HttpResponse インスタンスはファイルとして使用できるため、CSV モジュールの Writer メソッドのパラメータとして HttpResponse を直接使用できます。
4. Writer.writerow メソッドは、コンテンツ行をファイルに書き込む役割を果たします。

上記のメソッドは、非 HTML 形式のコンテンツを返すための一般的なパターンです。つまり、特定の MIME タイプの HttpResponse を作成し、それをパラメータとしてファイルを受け取るメソッドに渡し、特定の形式でドキュメントを生成します。そして応答を返します。

PDF 形式でコンテンツを生成する

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 タイプを使用して、PDF ファイルが返されることをブラウザーに伝えます。 HTML の代わりに、それ以外の場合はブラウザー これは通常の HTML コンテンツとして扱われます。
2. Canvas.Canvas メソッドはパラメータとしてファイルのようなオブジェクトを期待し、HttpResponse をメソッドに渡します。
3. Canvas インスタンスのメソッドを使用して PDF ドキュメントを描画し、showPage() メソッドと save() メソッドを呼び出します (そうしないと、破損した PDF ドキュメントが生成されます)。
4. 最後に HttpResponse インスタンスを返します

より複雑な PDF ドキュメントを生成します。ここでは、cStringIO ライブラリを使用して PDF ファイルを一時的に保存します

他の可能な形式を確認します
本質的に、ファイルを書き込むことができる Python ライブラリはすべて組み合わせることができますDjango の HttpResponse を使用して、ZIP ファイル、動的画像、チャート、XLS ファイルなどの特定の形式でコンテンツを返します。

最後に、xls ファイルを返す例を見てみましょう

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
ログイン後にコピー
プロセスは、コメントなしで上記と同じです。

さらに、特定の形式でコンテンツを正しく返すには、ここでのリクエストをフォームを通じて送信する必要があることに注意することが重要です。リクエストが Ajax を通じて開始された場合、返されたコンテンツはテキスト文字列として扱われ、返されることはできません。ブラウザによって特定のコンテンツとして解釈されます。
例:
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
ログイン後にコピー
さんは、開発プロセス中に発生した問題、つまりフォームのコンテンツを文字列にシリアル化する際の問題を記録する必要があると述べました。
場合によっては、フォーム内のすべてのコンテンツをキーと値のペアの文字列にシリアル化し、URL パラメーターを全体として渡す必要があり、値に含まれる特殊文字をエンコードする必要があります。たとえば、次のような形式があります。

$.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();
ログイン後にコピー
2 番目のテキスト型入力の値、チェックボックス型入力の値、および送信型入力の値がシリアル化されていないのはなぜですか?これは、フォーム要素の値をシーケンス文字列に含める場合、要素で name 属性を使用する必要があるためです。 2 番目のテキスト タイプ入力には name 属性がありません。チェックボックス タイプの入力の 1 つがチェックされていないため... Serialize() は、「成功したコントロール」のみを文字列にシリアル化します。ボタンを使用してフォームを送信しない場合、送信ボタンの値はシリアル化されないため、送信タイプの入力もシリアル化されません。
もちろん、フォーム全体を直接シリアル化するだけでなく、