UnicodeDecodeError with Django's request.FILES

2020-06-04 05:19发布

I have the following code in the view call..

def view(request):
    body = u""  
    for filename, f in request.FILES.items():
        body = body + 'Filename: ' + filename + '\n' + f.read() + '\n'

On some cases I get

UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 7470: ordinal not in range(128)

What am I doing wrong? (I am using Django 1.1.)

Thank you.

标签: python django
4条回答
何必那么认真
2楼-- · 2020-06-04 05:35

Anurag's answer is correct. However another problem here is you can't for certain know the encoding of the files that users upload. It may be useful to loop over a tuple of the most common ones till you get the correct one:

encodings = ('windows-xxx', 'iso-yyy', 'utf-8',)
for e in encodings:
    try:
        data = f.read().decode(e)
        break
    except UnicodeDecodeError:
        pass
查看更多
Deceive 欺骗
3楼-- · 2020-06-04 05:45

Django has some utilities that handle this (smart_unicode, force_unicode, smart_str). Generally you just need smart_unicode.

from django.utils.encoding import smart_unicode
def view(request):
    body = u""  
    for filename, f in request.FILES.items():
        body = body + 'Filename: ' + filename + '\n' + smart_unicode(f.read()) + '\n'
查看更多
We Are One
4楼-- · 2020-06-04 05:49

If you are not in control of the file encoding for files that can be uploaded , you can guess what encoding a file is in using the Universal Encoding Detector module chardet.

查看更多
▲ chillily
5楼-- · 2020-06-04 05:55

you are appending f.read() directly to unicode string, without decoding it, if the data you are reading from file is utf-8 encoded use utf-8, else use whatever encoding it is in.

decode it first and then append to body e.g.

data = f.read().decode("utf-8")
body = body + 'Filename: ' + filename + '\n' + data + '\n'
查看更多
登录 后发表回答