Python 使用Django(动态内容)生成CSV文件
在my view.py中,我有两个函数,一个用于处理表单输入并输出过滤列表,另一个用于将此列表导出到CSV 下面是我的第一个函数的返回:Python 使用Django(动态内容)生成CSV文件,python,django,csv,Python,Django,Csv,在my view.py中,我有两个函数,一个用于处理表单输入并输出过滤列表,另一个用于将此列表导出到CSV 下面是我的第一个函数的返回: return render_to_response('templateX.html', { 'queryset': queryset, 'filter_form': filter_form, 'validated': validated, }, context_instance = RequestContext(request) ) 以下是导出功能
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
我不知道如何从我的第一个函数中获取查询集,该函数包含我希望在CSV中使用的项目列表,并在导出到CSV函数中使用它。
或者,最好的方法是将这两个功能结合起来,让用户单击复选框以确定是否要下载CSV文件。
任何帮助都将不胜感激。IMHO,最好将它们组合起来,并从显式查询集生成CSV数据。然后可以将其改写为一般性内容,如(未测试): 您可以这样使用:
def my_view(request):
calls = Call.objects.all()
return export_to_csv(request, calls, fields = ('calldate', 'src', 'dst'))
--
您提供的示例代码假定QuerySet是在会话数据中设置的,这可能会导致大量错误和安全问题。如果将会话存储在数据库中,最终可能会读取数据,而只是以效率低得多的形式将其写回。我找到了一种与knutin不同的方法。 我在函数或全局变量之外声明了一个名为csv_list=[]的空列表 在我的主函数(根据用户输入进行处理和筛选的函数)中,我将此csv_列表设置为全局,以便将其设置为queryset的“更新”版本。 然后,要生成csv,只需执行以下操作: 对于呼叫csv_列表: writer.writerow([call.src,call.dst]) 返回响应
它现在运行正常。我建议将它们合并到一个视图函数中,该函数需要一个额外的参数:
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"),
下面接收Django查询集并输出CSV文件 用法:: 从utils导入dump2csv 从dummy_app.models导入* qs=DummyModel.objects.all() dump2csv.dump(qs'。/data/dump.csv') 剧本:
import csv
from django.db.models.loading import get_model
def dump(qs, outfile_path):
model = qs.model
writer = csv.writer(open(outfile_path, 'w'))
headers = []
for field in model._meta.fields:
headers.append(field.name)
writer.writerow(headers)
for obj in qs:
row = []
for field in headers:
val = getattr(obj, field)
if callable(val):
val = val()
if type(val) == unicode:
val = val.encode("utf-8")
row.append(val)
writer.writerow(row)
使用全局函数通过视图传递数据是危险的;Django可以线程化,这可能会在部署时中断。您在自己测试时不会看到此错误,而且由于它是基于竞争条件的,因此很难跟踪它。您能否详细说明其危险性以及它在部署时可能如何崩溃?用户1会发布一个表单请求。这将调用设置
csv\u列表的查看函数。用户2执行同样的操作,再次设置csv\u列表
。用户1然后导出CSV,并通过CSV\u列表
获取用户2的数据。好的,得到了。这是灾难性的。我试过这样做,但是当我点击我的“导出”按钮,它指向url:localhost:8000/cdr/export_csv,它会丢失所有GET请求,因此没有处理queryset,所以我的csv文件是空的。那么,我的“导出”按钮如何像单击“搜索”按钮一样发送所有请求呢?您的导出按钮应该1)以导出URL为目标并包含查询参数,或者2)作为具有查询参数的表单的一部分,如有必要,作为隐藏字段。我很难提出具体的建议,因为我不完全清楚您的页面之间的关系。是的,我决定按照您描述的第一种方式来做。现在‘隐藏字段’很有趣,当我遇到类似情况时,我将稍后再看它。隐藏字段是
。我不知道Django是否有一些特殊的魔法来生成它们,但它们很容易由您自己生成。请记住,即使表单参数来自隐藏字段,也不要隐式信任它。验证它。mimetype
应该是content\u type
。现在变了
import csv
from django.db.models.loading import get_model
def dump(qs, outfile_path):
model = qs.model
writer = csv.writer(open(outfile_path, 'w'))
headers = []
for field in model._meta.fields:
headers.append(field.name)
writer.writerow(headers)
for obj in qs:
row = []
for field in headers:
val = getattr(obj, field)
if callable(val):
val = val()
if type(val) == unicode:
val = val.encode("utf-8")
row.append(val)
writer.writerow(row)