使用Django生成CSV文件(动态内容)

7 投票
4 回答
13632 浏览
提问于 2025-04-16 06:24

在我的view.py文件里,我有两个函数,一个是处理表单输入并输出过滤后的列表,另一个是将这个列表导出为CSV文件。

这是我第一个函数的返回结果:

return render_to_response('templateX.html',
{
 'queryset': queryset,
 'filter_form': filter_form,
 'validated': validated,
},
 context_instance = RequestContext(request)
 )

这是导出函数:

def export_to_csv(request):
    # get the response object, this can be used as a stream.
    response = HttpResponse(mimetype='text/csv')
    # force download.
    response['Content-Disposition'] = 'attachment;filename=export.csv'
    # the csv writer
    writer = csv.writer(response)
    qs = request.session['queryset']
    for cdr in qs:
        writer.writerow([cdr['calldate'], cdr['src'], cdr['dst'], ])
    return response   

我不太确定怎么从我的第一个函数中获取queryset,这个queryset里包含了我想放进CSV文件的项目列表,然后在我的export_to_csv函数中使用它。或者,最好的办法是把这两个函数合并,让用户勾选一个复选框,选择是否要下载CSV文件。希望能得到一些帮助。

4 个回答

0

我找到了一种不同于knutin的方法来实现这个功能。 我在函数外面声明了一个空列表,叫做csv_list = [],这就是一个全局变量。

在我的主函数中(这个函数根据用户输入来处理和过滤数据),我把这个csv_list设为全局变量,这样它就可以被更新为“最新”的查询结果。然后生成csv文件就简单多了,只需要这样做: for call in csv_list: writer.writerow([call.src, call.dst]) return response

现在这个方法运行得还不错。

4

在我看来,最好的办法是把它们结合起来,从一个明确的查询集中生成CSV数据。这样可以改写成一些通用的东西,比如(没有测试过):

def export_to_csv(request, queryset, fields):
    response = ...
    writer = csv.writer(response)
    for obj in queryset:
        writer.writerow([getattr(obj, f) for f in fields])
    return response

你可以这样使用:

def my_view(request):
    calls = Call.objects.all()
    return export_to_csv(request, calls, fields = ('calldate', 'src', 'dst'))

--

你提供的示例代码假设查询集存储在会话数据中,这可能会导致很多错误和安全问题。如果你把会话存储在数据库里,可能会出现读取数据后再以一种效率更低的方式写回去的情况。

7

我建议把这些合并成一个视图函数,并增加一个额外的参数:

def my_view(request, exportCSV):
    # ... Figure out `queryset` here ...

    if exportCSV:
        response = HttpResponse(mimetype='text/csv')
        response['Content-Disposition'] = 'attachment;filename=export.csv'
        writer = csv.writer(response)
        for cdr in queryset:
            writer.writerow([cdr['calldate'], cdr['src'], cdr['dst'], ])
        return response
    else:
        return render_to_response('templateX.html', {'queryset': queryset,
            'filter_form': filter_form, 'validated': validated},
            context_instance = RequestContext(request))

然后,在你的 urls.py 文件中,可以在 urlpatterns 里放一些这样的内容:

url(r'^form', 'my_view', {"exportCSV": False}, name="form"),
url(r'^csv', 'my_view', {"exportCSV": True}, name="export"),

撰写回答