Django如何最好地解决unicode错误

时间:2012-01-05 20:39:33

标签: django unicode

我的观点如下:

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>

2 个答案:

答案 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])