2009-11-09 20 views
5

Tôi đã đoạn mã sau trong cuộc gọi xem ..UnicodeDecodeError với request.FILES của Django

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

Trên một số trường hợp tôi nhận được

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

Tôi đang làm gì sai? (Tôi đang sử dụng Django 1.1.)

Cảm ơn bạn.

Trả lời

4

Django có một số utilities xử lý điều này (smart_unicode, force_unicode, smart_str). Nói chung bạn chỉ cần 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' 
+0

Cảm ơn và tôi sẽ upvote tất cả các bạn một khi đã đăng ký =) –

4

bạn đang phụ f.read() trực tiếp đến chuỗi unicode, mà không cần giải mã nó, nếu các dữ liệu bạn đang đọc từ tập tin là utf-8 mã hóa sử dụng utf-8, nếu không sử dụng bất cứ mã hóa nó là trong.

giải mã trước và sau đó nối vào phần thân ví dụ:

data = f.read().decode("utf-8") 
body = body + 'Filename: ' + filename + '\n' + data + '\n' 
4

Câu trả lời của Anurag là chính xác. Tuy nhiên một vấn đề khác ở đây là bạn không thể biết chắc chắn về việc mã hóa các tệp mà người dùng tải lên. Nó có thể hữu ích để lặp qua một tuple trong những phổ biến nhất cho đến khi bạn có được đúng một:

encodings = ('windows-xxx', 'iso-yyy', 'utf-8',) 
for e in encodings: 
    try: 
     data = f.read().decode(e) 
     break 
    except UnicodeDecodeError: 
     pass 
3

Nếu bạn không kiểm soát được mã hóa tập tin cho các tập tin có thể được tải lên, bạn có thể đoán những gì mã hóa một tệp đang sử dụng mô-đun Universal Encoding Detectorchardet.

+0

+1 Điều này hữu ích. – shanyu

Các vấn đề liên quan