Django, как лучше всего решать ошибки Unicode - PullRequest
0 голосов
/ 06 января 2012

У меня есть представление в следующем виде:

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'

Так, как мне лучше всего справиться с этой первой ошибкой, при этом гарантируя, что поля не генерируют вторуютип ошибок?Должен ли я иметь дело с этим на уровне представления, или это можно позаботиться в моделях?

Ответы [ 2 ]

2 голосов
/ 06 января 2012

Посмотрите на 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 должен работать с любой глубиной отношения.

0 голосов
/ 06 января 2012

Итак, для полноты.Вот мой рабочий код:

# 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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...