вторник, 19 марта 2013 г.

Django UnicodeEncodeError: 'ascii' codec can't encode character Решение проблемы

При работе с Django во время записи русского текста в кодировке UTF-8 в файл может возникнуть исключение вида

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa1'
in position 0: ordinal not in range(128)


Такое исключение в Django может возникнуть, например, при выполнении такого кода:

#-*- coding: utf-8 -*-
import os

from django.template import Template, Context, loader
from django.http import HttpResponse

def write_file(request):
    pathToFile = os.path.join(os.path.dirname(__file__), 'files/newtext.txt')
    file = open(pathToFile, 'w')
    text_for_file = u'Привет! Я новый файл!'
    file.write(text_for_file)
    file.close()
    file = open(pathToFile, 'r')
    text_from_file = file.read()
    file.close()
    t = loader.get_template('filework.html')
    c = Context({'text': text_from_file})
    renderedTemplate = t.render(c)
    return HttpResponse(renderedTemplate)

Для устранения данной проблемы можно воспользоваться функцией smart_str(), имеющейся в Django, внеся в наш пример следующие две добавки:

#-*- coding: utf-8 -*-
import os

from django.template import Template, Context, loader
from django.http import HttpResponse
from django.utils.encoding import smart_str, smart_unicode

def open_file(request):
    pathToFile = os.path.join(os.path.dirname(__file__), 'files/mytext.txt')
    file = open(pathToFile, 'r')
    text_from_file = file.read()
    file.close()
    t = loader.get_template('filework.html')
    c = Context({'text': text_from_file})
    renderedTemplate = t.render(c)
    return HttpResponse(renderedTemplate)

def write_file(request):
    pathToFile = os.path.join(os.path.dirname(__file__), 'files/newtext.txt')
    file = open(pathToFile, 'w')
    text_for_file = u'Привет! Я новый файл!'
    file.write(smart_str(text_for_file))
    file.close()
    file = open(pathToFile, 'r')
    text_from_file = file.read()
    file.close()
    t = loader.get_template('filework.html')
    c = Context({'text': text_from_file})
    renderedTemplate = t.render(c)
    return HttpResponse(renderedTemplate)

Комментариев нет:

Отправить комментарий