我的观点如下:
def export(request, exportCSV):
if exportCSV:
...
# get a list of results named list
...
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=myfile.csv'
writer = csv.writer(response)
writer.writerow(['firstfield', 'secondfield', ... ,])
for item in list:
writer.writerow([item.firstfield, item.secondfield, ... ,])
return response
问题是某些字段包含西班牙文本,并且此类字段会引发以下错误:
'ascii' codec can't encode character u'\xe9' in position 3: ordinal not in range(128)
现在,如果我将.encode('utf8)
附加到有问题的字段,那么一切都很好:
...
for item in list:
writer.writerow([item.firstfield.encode('utf8'), item.secondfield.encode('utf8'), ... ,])
然而,将此附加到每个字段显然违反了DRY。此外,并非每个字段都接受此编码。如果我附加到某些字段,我会生成此错误:
'int' object has no attribute 'encode'
或:
'NoneType' object has no attribute 'encode'
那么我如何才能最好地处理第一个错误,同时确保字段不会产生第二类错误?我是否应该在视图级别处理此问题,还是可以在模型中处理它?</ p>
答案 0 :(得分:2)
请在此处查看smart_str
和其他转化功能:https://docs.djangoproject.com/en/dev/ref/unicode/#conversion-functions
为了保持干爽,你可以像这样使用它......
my_fields = ['firstfield', 'secondfield', 'thirdfield']
for item in list:
writer.writerow([smart_str(getattr(item, x)) for x in my_fields])
编辑 FK关系
尝试类似(未经测试的)......
def get_field(obj, field):
value = obj
for f in field.split('.'):
value = getattr(value, f)
return value
my_fields = ['firstfield.firstsubfield', 'secondfield.sub.subsub', 'thirdfield']
for item in list:
writer.writerow([smart_str(get_field(item, x)) for x in my_fields])
get_field
方法适用于任何关系深度。
答案 1 :(得分:0)
所以,为了完整性。这是我的工作代码:
# get_field function
def get_field(obj, field):
value = obj
for f in field.split('.'):
value = getattr(value, f)
return value
def csv(request, exportCSV)
...
if exportCSV:
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=myfile.csv'
writer = csv.writer(response)
# write headings
writer.writerow([
'Verbose Heading FirstField',
'Verbose Heading ScondField',
])
# create list of fields as objects
fields_list = [
'subfield1.subsubfield1.subsubsubfield1',
'subfield1.subfield2',
]
for item in results_list:
writer.writerow([smart_str(get_field(item, x)) for x in fields_list])