我正在编写一款应用程序,可跟踪2名玩家之间的一系列比赛。我正在使用Django的User
模型并使用我自己的UserProfile
进行扩展。
我将用户名存储在User
中作为他们的steamID(例如:76561197965801299
),然后在登录时查找他们的用户名,并更新UserProfile
。
我不想查看76561197965801299
,而是想查看用户名,在一个页面上,我想用更多好东西装饰这个用户名,所以我写了一个模板标签。
问题:
我似乎无法从模板标签中打印unicode数据。
实际错误:
'ascii'编解码器无法对位置16中的字符u'\ u260e'进行编码:序数 不在范围内(128)
通常Django不会因为unicode问题而烦恼(例如:我可以在管理页面中看到这个unicode对象没问题)但我从未尝试过应用模板标签,所以显然我正在做的事情这里错了。
模板/梯/ 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
当我在浏览器中查看此内容时,我收到上述错误:
/ ladder / dota2 /'ascii'编解码器中的UnicodeEncodeError无法编码 字符u'\ u260e'在位置16:序数不在范围内(128)
有用的暗示:
Unicode错误提示
无法编码/解码的字符串是:oose☎
我曾多次尝试浏览Django文档,我尝试使用force_text()
无效,但由于我有点不清楚为什么这不起作用,我可能会失踪相关部分。此模板标记适用于名称没有unicode的情况。
答案 0 :(得分:5)
steam_string = "<a href='{0}' alt='{1}\'s profile'><img src='{2}' alt='{1}\'s avatar' >{1}</a>".format(url, handle, avatar)
.format()
方法不会将格式字符串从字节提升为unicode,因为格式化参数中有unicode字符串。 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))
答案 1 :(得分:3)
我可能会非常简单地以错误的方式思考这个问题,但是,如果你只是通过在字符串前加上字母'u'来告诉django它是一个unicode。
类似的东西:
unicodeString = "ís"
string = u"this -> %s my unicode string" % unicodeString
如果我根本不理解你的问题,我很抱歉。 (我无法发表评论,所以我发布了答案)