我有一个函数,它接受 QuerySet
并呈现 CSV。我想编写一个 View ,呈现一个模板,其中包含下载不同 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
目前我正在编写一个不可重用的 View :
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 对应于下载不同的内容。
新 View 看起来像:
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('/')
有更好的方法吗?
最佳答案
创建一个字典,将给定的代码映射到关联的对象,然后将所有 if 语句减少为一个 if。对于文件名,看起来你每次都在做同样的事情,即复数和小写,在这种情况下,你应该在 model._meta.verbose_name_plural 中设置它,然后在需要时访问它:
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('/')
关于python - 编写可重用 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22736116/