django中如何生成非HTML格式的内容。

某些时候可能有这样的需求,在网页中点击一个链接或者一个按钮希望返回一张图片、一个pdf文档、一个csv文档等而非HTML。在diango中很容易做到这些。django中的view用来接收http request并返回web response。通常情况下,返回的内容为HTML,但其能够返回的不仅仅如此,还可以是上述图片、pdf文件等等。返回非HTML形式的内容的关键在于HttpResponse这个类,尤其是mimetype这个参数,通过将此参数设置为不同的值可以提示浏览器view返回了不同格式的内容。比如,想要返回图片内容,只需读如一张图片,然后在HttpResponse中指明图片的mimetype并将图片内容作为另一参数response给浏览器,浏览器能够自动正确的显示图片内容。

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")

另外一个需要特别注意的的是HttpResponse对象实现了Python的标准“file-like-object”API,也即可以将HttpResponse当做文件使用。

例子:

生成CSV格式的内容

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

需要注意的几点:

1.HttpResponse中mimetype指定为了‘text/csv‘告知浏览器返回的文档是CSV文件。

2.HttpResponse设置了另外一个参数Content-Disposition其中attachment告知浏览器保存返回的文档而非显示其内容,filename指明了返回文档的名字,改名字可任意指定。

3.因为csv的writer方法期望一个文件类型的对象作为参数,而HttpResponse实例可以当做文件使用,所以可以直接在csv模块的writer方法中将HttpResponse作为参数。

4.writer.writerow方法负责往文件中写入一行内容。

上述方法是返回非HTML格式内容的通用模式,也即:创建一个特定MIME Type的HttpResponse,将其传递给以文件为参数产生特定格式的文档的方法,之后返回该response。

生成PDF格式的内容

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

流程基本同上,需要注意的几点:

1.此处使用了 application/pdf MIME type告知浏览器返回的是PDF文件,而非HTML,否则浏览器会将其作为普通HTML内容处理。

2.canvas.Canvas方法期望一个file-like的对象作为参数,将HttpResponse传递给该方法。

3.使用Canvas实例的方法绘制PDF文档,调用showPage()方法和save()方法(否则会产生损坏的pdf文档)。

4.最后返回该HttpResponse实例

生成更为复杂的PDF文档,这里使用了cStringIO库来临时存放PDF文件

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

其他可能的格式

实质上,任何可以写文件的Python库都可与Django的HttpResponse结合用以返回特定格式的内容,如ZIP文件、动态图片、图表、XLS文件等等。

最后在看一个返回xls文件的例子

from django.http import HttpResponse
import xlwt
def 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必须是通过表单提交才能正确返回特定格式的内容,若要是通过ajax方式发起的request则返回的内容会被当做文本串处理,而不能被浏览器解释为特定内容。

比如:

$.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();

说到这里有必要记录一下开发过程中遇到的一个问题,也即将表单内容序列化为字符串的问题。

有时需将表单中的所有内容序列化为键值对构成的串做为一个整体进行URL参数传递,而且需要对值中包含的特殊字符进行编码。比如有如下表单:

<form>

  <div><input type="text" name="a" value="1" id="a" /></div>

  <div><input type="text"  value="2" id="b" /></div>

  <div><input type="hidden" name="c" value="3" id="c" /></div>

  <div>

    <textarea name="d" rows="8" cols="40">4</textarea>

  </div>

  <div><select name="e">

    <option value="5" selected="selected">5</option>

    <option value="6">6</option>

    <option value="7">7</option>

  </select></div>

  <div>

    <input type="checkbox" name="f" value="8" id="f" />

  </div>

  <div>

    <input type="submit" name="g" value="Submit" id="g" />

  </div>

</form>

$('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对象序列化,如<input>,<textarea>等等。

时间: 2024-10-09 18:20:40

django中如何生成非HTML格式的内容。的相关文章

在MDK中如何生成*.bin格式的文件?

在Realview MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件.虽然这两个格式的文件非常有利于ULINK2仿真器的下载和调试,但是ADS的用户更习惯于使用*.bin格式的文件,甚至有些嵌入式软件开发者已经拥有了*.bin格式文件的调试或烧写工具.为了充分地利用现有的工具,同时发挥Realview MDK集成开发环境的优势,将*.axf格式文件或*.hex格式文件转换成*.bin格式的文件是十分自然的想法.本文将详细的探讨这种转换方法. 在详细的

Django中的日期处理注意事项和自定义时间格式转换

我们在用Django创建models时,常常会涉及时间日期字段的处理,Django里日期相关Field有DateTimeField.DateField和TimeField三种类型,看似简单,但其中有一些容易出错的地方需要注意:另外,如果不习惯Django的默认时间格式,也可以自定义的修改. DateTimeField.DateField和TimeField,其值分别对应着Python里的datetime.datetime.datetime.date和datetime.time三个实例,这三个Fi

Django中生成随机验证码

Django中生成随机验证码 1.html中a标签的设置 1 <img src="/get_validcode_img/" alt=""> 2.views中的get2.views中的getvalidcode_img设置 导入文件 1 import json 2 import os 3 import random 4 from django.contrib import auth 5 from django.shortcuts import render,

Django 中的用户认证

Django 自带一个用户认证系统,这个系统处理用户帐户.组.权限和基于 cookie 的 会话.本文说明这个系统是如何工作的. 概览 认证系统由以下部分组成: 用户 权限:控制用户进否可以执行某项任务的二进制(是/否)标志. 组:一种为多个用户加上标签和权限的常用方式. 消息:一种为指定用户生成简单消息队列的方式. Deprecated in Django 1.2: 认证系统的消息部分将会在 Django 1.4 版中去除. 安装 认证系统打包在 Django 的 django.contrib

django中HttpRequest请求

视图的第一个参数必须是HttpRequest对象 在视图函数中,接收的request有如下属性: path:一个字符串,表示请求的页面的完整路径,不包含域名. method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'.'POST'. 在浏览器中给出地址发出请求采用get方式,如超链接. 在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求. encoding:一个字符串,表示提交的数据的编码方式. 如果为None则表示使用浏览器的默认设置

Django中的Model继承

Django 中的 model 继承和 Python 中的类继承非常相似,只不过你要选择具体的实现方式:让父 model 拥有独立的数据库:还是让父 model 只包含基本的公共信息,而这些信息只能由子 model 呈现. Django中有三种继承关系: 1.通常,你只是想用父 model 来保存那些你不想在子 model 中重复录入的信息.父类是不使用的也就是不生成单独的数据表,这种情况下使用抽象基类继承 Abstract base classes. 2.如果你想从现有的Model继承并让每个

在Django中使用Q()对象

转载于:  http://www.smallerpig.com/1000.html 问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>> q1 = Entry.objects.filter(headline__startswith="What") >>> q2 = q1.exclude(pub_date__gte=datetime.date.today()) >>> q3 = q1

Django中的CSRF

CSRF(Cross Site Request Forgery, 跨站域请求伪造) CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一.其他安全隐患,比如 SQL 脚本注入,跨站域脚本攻击等在近年来已经逐渐为众人熟知,很多网站也都针对他们进行了防御.然而,对于大多数人来说,CSRF 却依然是一个陌生的概念.即便是大名鼎鼎的 Gmail, 在 2007 年底也存在着 C

Django中视图总结[urls匹配,HttpRequest对象,HttpResponse对象,对象序列化接受及案例]

视图的功能: 接收请求,进行处理,返回应答. 视图返回的内容为: HttpResponse的对象或子对象 render 返回的是HttpResponse的对象 JsonResponse是HttpResponse的子类 HttpResponseRedirect也是HttpResonse的子类 redirect是HttpResponseRedirect的一个简写 总结:所以视图返回的内容一般为:render,redirect,JsonResponse,Httpresponse 定义视图函数分为两步