我有这个功能需要QuerySet
并呈现CSV。我想写一个视图,提供一个模板,其中包含下载不同CSV文件的选项(基本上是 models.py 中定义的任何内容)
# Exports CSV file using a QuerySet
def export(qs, fields=None, file_name='data'):
model = qs.model
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename={0}-{1}.csv'.format(file_name, str(datetime.date.today()))
writer = csv.writer(response)
# Write headers to CSV file
if fields:
headers = fields
else:
headers = []
for field in model._meta.fields:
headers.append(field.name)
writer.writerow(headers)
# Write data to CSV file
for obj in qs:
row = []
for field in headers:
if field in headers:
val = getattr(obj, field)
if callable(val):
val = val()
row.append(val)
writer.writerow(row)
# Return CSV file to browser as download
return response
目前我正在编写一个不可重复使用的视图:
def csv_of_surveys(request):
r = export(Survey.objects.all(), file_name='surveys')
return r
我该怎么办?我唯一的想法是发送一个代码并写一个switch语句,所以
{% url "csv_of" 0 %}
{% url "csv_of" 1 %}
{% url "csv_of" 2 %}
{% url "csv_of" 3 %}
其中0,1,2和3对应于下载不同的东西。
新视图看起来像:
def csv_of(request, code):
if code == 0:
r = export(Survey.objects.all(), file_name='surveys')
return r
elif code == 1:
r = export(User.objects.all(), file_name='teachers')
return r
elif code == 2:
r = export(Student.objects.all(), file_name='students')
return r
# ...
else:
return HttpResponseRedirect('/')
有更好的方法吗?
答案 0 :(得分:1)
创建一个字典,将给定代码映射到关联对象,然后将所有if语句减少为一个if。对于文件名,看起来你每次都做同样的事情,这是多元化和小写它,在这种情况下你应该在model._meta.verbose_name_plural中设置它,然后在你需要时访问它:< / p>
file_codes = {0:Survey,1:User...}
def csv_of(request, code):
if int(code) in file_codes.keys():
obj = file_codes[int(code)]
return export(obj.objects.all(), file_name = obj._meta.verbose_name_plural.title())
else:
return HttpResponseRedirect('/')