zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    深(爆)搜专题整理
    牛客CSP-S提高组赛前集训营1 T2:乃爱与城市拥挤程度
    [BZOJ3743][Coci2015]Kamp 题解
    CSP2019-S,J初赛游记
    指针复习
    二叉树复习
    最短路复习
    数据库关联查询与模型之间的关联
    数据库操作Flask-SQLAlchemy之模型声明及数据库表的生成与删除
    csrf攻击防范
  • 原文地址:https://www.cnblogs.com/qwj-sysu/p/4261249.html
Copyright © 2011-2022 走看看