django “如何”系列9:三合一:利用遗留的数据库、输出csv和输出pdf

如何集成遗留的数据库

django在适合开发新应用的同时,可以可以集成以前遗留的数据库,下面是如何集成一个已经存在的数据库的流程。

给定你的数据库的参数

你需要告诉django你的数据库连接参数以及数据库的名字,你可以通过修改django配置文件的DATABASES中的default连接来给定你的数据库参数

  • NAME
  • ENGINE
  • USER
  • PASSWORD
  • HOST
  • PORT

自动生成模型

django自带了一个工具inspectdb,这个工具可以通过反溯一个已经存在的数据库来创建一个模型

python manage.py inspectdb

 

你可以直接使用重定向输出到一个文件里面

python manage.py inspectdb > models.py

 

生成其他的核心表格

inspectdb指定反溯创建已经有的数据库表,我们仍然需要创建其他的核心表格,比如admin权限等等

python manage.py syncdb

 

测试和调整

通过各种方法测试和调整这些模型知道符合你的要求。建议通过django数据库api访问数据,通过django的admin站点编辑数据和根据需要调整你的模型文件。

使用django输出csv

这里主要介绍如何动态的使用django的视图函数去输出csv文件。你可以是用python的csv库或者django模板系统

使用python的csv库

python自带一个csv库csv。在django中使用这个库的关键在于:csv模块的csv创建能力作用于类文件对象,django的HttpResponse对象就是类文件对象。下面是一个例子:

import csv
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype=text/csv)
    response[Content-Disposition] = attachment; filename="somefilename.csv"

    writer = csv.writer(response)
    writer.writerow([First row, Foo, Bar, Baz])
    writer.writerow([Second row, A, B, C, "Testing", "Here‘s a quote"])

    return response

 

代码和注释是一目了然的,但是还是有一些东西值得一提:

  • 响应得到一个特别的MIME类型‘text/csv‘,如果没有这个的话,浏览器可能把输出解释成一个html,那是一个丑陋可怕的官网文章。
  • 响应得到一个额外的Content-Disposition头部,包含了csv文件的文件名,这个文件名在另存为窗口会用到
  • 钩进csv生成器api是非常简单的,csv.writer接受一个类文件对象,而HttpResponse对象刚好符合
  • writer.writerow接受一个可迭代的对象(列表或者元组)
  • csv模块为你注意了引号,需要把原始的字符串穿进去就好了

处理Unicode

python的csv模块不支持Unicode输入,因为django只在内部使用unicode,这意味着,从某些源(比如HttpReuqest)的字符串是有潜在问题的。下面是一些处理的方法:

  • 手工把所有的unicode对象编码成一个兼容的编
  • 使用UnicodeWriter类
  • 使用python-unicode 模块

使用模板系统输出csv

想法:给你的模板传递一个对象的列表,然后再模板中使用for循环输出逗号。

这是一个例子:

from django.http import HttpResponse
from django.template import loader, Context

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype=text/csv)
    response[Content-Disposition] = attachment; filename="somefilename.csv"

    # The data is hard-coded here, but you could load it from a database or
    # some other source.
    csv_data = (
        (First row, Foo, Bar, Baz),
        (Second row, A, B, C, "Testing", "Here‘s a quote"),
    )

    t = loader.get_template(my_template_name.txt)
    c = Context({
        data: csv_data,
    })
    response.write(t.render(c))
    return response
{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
{% endfor %}

 使用django输出pdf

django使用一个优秀的开源python库ReportLab来输出pdf文件的

安装ReportLab

可以直接去网上搜索下载或者直接用命令行安装都可以

http://www.reportlab.com/software/opensource/rl-toolkit/download/

安装完成后直接导入就可以使用了

 import reportlab

在视图函数中使用

类似csv模块,ReportLab的api也是作用于类文件对象的,而django的HttpResponse对象也是类文件对象,下面是一个简单的例子:

from reportlab.pdfgen import canvas
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(mimetype=application/pdf)
    response[Content-Disposition] = attachment; filename="somefilename.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

 

最后的showPage()和save()对于pdf文件来说是很重要的,其他的注意事项和输出csv文件的差不多,可以参考着看

复杂的pdf

如果你想创建复杂的pdf,考虑使用cStringIO临时存放你的pdf文件

# Fall back to StringIO in environments where cStringIO is not available
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(mimetype=application/pdf)
    response[Content-Disposition] = attachment; filename="somefilename.pdf"

    buffer = StringIO()

    # Create the PDF object, using the StringIO object as its "file."
    p = canvas.Canvas(buffer)

    # 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.
    pdf = buffer.getvalue()
    buffer.close()
    response.write(pdf)
    return response

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。