2013-09-18 4 views
0

Я пишу приложение, которое будет отслеживать серию матчей между 2 игроками. Я использую модель Django User и расширяю ее своими UserProfile.Не удается получить тег шаблона django для возврата unicode

Я храню имена пользователей в User как их steamID (например: 76561197965801299), а затем просматривают имя своего парольного имени при входе в систему и обновляют UserProfile.

Вместо того, чтобы смотреть на 76561197965801299, я хочу посмотреть имя пользователя, и на одной странице я хочу украсить это имя пользователя большим количеством положительных героев, поэтому я написал шаблонный тег.

Проблема:

Я не могу напечатать Юникода данные из моего шаблона тега.

Фактическая ошибка:

'ascii' codec can't encode character u'\u260e' in position 16: ordinal not in range(128)

Обычно Джанго не беспокоит меня вопросами Юникода (например: Я могу видеть это юникод объект в страницах администрирования не проблема), но я никогда не пробовал применять тег шаблона, поэтому, очевидно, что-то я делаю неправильно здесь.

шаблон/лестницы/match_game_listing.html

{{ match.challengee|steam_name }} 

match.challengee в этом случае 76561197971597000.

лестница/templatetags/ladder_filters.py

from django import template 
from django.contrib.auth.models import User 
from django.core.exceptions import ObjectDoesNotExist 
from django.utils.html import mark_safe 
from cafe.models import UserProfile 

register = template.Library() 

@register.filter() 
def steam_name(name): 
    try: 
     user_obj = User.objects.get(username=name) 
     user_prof = UserProfile.objects.get(user_id=user_obj.id) 

     url = user_prof.url 
     handle = unicode(user_prof.handle) 
     avatar = user_prof.avatar 

     steam_string = "<a href='{0}' alt='{1}\'s profile'><img src='{2}' alt='{1}\'s avatar' >{1}</a>".format(url, handle, avatar) 

     return mark_safe(steam_string) 

    # Non-steam entities can exist, ignore 
    except ObjectDoesNotExist: 
     return name 

Когда я иду, чтобы просмотреть в браузере, я получаю вышеупомянутую ошибку:

UnicodeEncodeError at /ladder/dota2/ 'ascii' codec can't encode character u'\u260e' in position 16: ordinal not in range(128)

С полезным намеком:

Unicode error hint

The string that could not be encoded/decoded was: oose ☎

Я пробовал просматривать Django docs num и я пробовал играть с force_text() безрезультатно, но поскольку я немного неясен, почему это не работает, я мог бы просто пропустить соответствующий раздел. Этот тег шаблона работает в тех случаях, когда имя не имеет юникода.

+0

ли http://stackoverflow.com/q/3828723/165603 помощь? – okm

ответ

5
steam_string = "<a href='{0}' alt='{1}\'s profile'><img src='{2}' alt='{1}\'s avatar' >{1}</a>".format(url, handle, avatar) 

.format() Метод не будет способствовать формату строки из байт в Юникод только потому, что является Юникод строки в параметрах форматирования.Выходной сигнал str.format всегда равен str, а выход unicode.format всегда равен unicode. Таким образом, он отличается от старого оператора %, где str % unicode -> unicode.

Поскольку вы хотите получать Unicode, ваша строка формата также должна быть Unicode (u""). Кроме того,

return mark_safe(steam_string) 

Почему вы отмечаете этот сейф? Это не так. Без HTML-экранирования любые HTML-специальные символы в отформатированных параметрах могут вызвать уязвимость HTML-инъекции, приводящую к атакам XSS. Кроме того, ваши апострофа являются неправильно сбежавшие:

"alt='{1}\'s profile'" 

\' представляет собой строку Python буквальным побег; вы будете возвращаться строку:

alt='someone's profile' 

, что означает, что вы никогда не увидите суффикс 's profile, поскольку он не является частью значения атрибута.

Предлагайте:

from django.utils.html import escape 
... 
return mark_safe(
    u'<a href="{0}" alt="{1}\'s profile">' 
     u'<img src="{2}" alt="{1}\'s avatar">{1}' 
    u'</a>' 
).format(escape(url), escape(handle), escape(avatar)) 
+0

Спасибо, это то, на что я надеялся - у меня было ощущение, что я делаю что-то совсем не так с этим. Это было очень полезно. – GordonsBeard

3

Возможно, я думаю об этом очень просто и неправильно, но, может быть, если вы просто скажете django его unicode, поместив букву «u» перед строкой.

что-то вроде:

unicodeString = "ís" 
string = u"this -> %s my unicode string" % unicodeString 

Я извиняюсь, если я не понял ваш вопрос вообще. (Я не могу комментировать, так что я отправил ответ)

Понял от чтения этого: https://docs.djangoproject.com/en/dev/ref/unicode/

+0

О, мужчина, сделай * Я * чувствую себя глупо. Это точно проблема. Переосмыслив его до максимума, большое вам спасибо. – GordonsBeard

+0

Рад, что я мог помочь. Я часто делаю то же самое ... – Ramalus

+0

Я использую 'from __future__ import unicode_literals' на Python 2 и использую Unicode везде, куда бы я ни пошел. – Matthias

Смежные вопросы