无法获取django模板标签返回unicode

Gor*_*ard 0 python django unicode django-templates

我正在编写一个应用程序来跟踪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 }}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

当我在浏览器中查看此内容时,我收到上述错误:

/ ladder/dota2 /'ascii'编解码器中的UnicodeEncodeError不能对位置16中的字符u'\ u260e'进行编码:序数不在范围内(128)

有用的暗示:

Unicode错误提示

无法编码/解码的字符串是:oose☎

我曾多次尝试浏览Django文档force_text(),但我尝试过玩无济于事,但由于我有点不清楚为什么这不起作用,我可能只是错过了相关部分.此模板标记适用于名称没有unicode的情况.

bob*_*nce 5

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

.format()方法不会将格式字符串从字节提升为unicode,因为格式化参数中存在unicode字符串.输出str.format始终str是,输出unicode.format始终是unicode.通过这种方式,它与旧的%运营商不同str % unicode -> unicode.

由于您需要Unicode输出,因此您的格式字符串也必须是Unicode(u""字符串).也,

return mark_safe(steam_string)
Run Code Online (Sandbox Code Playgroud)

你为什么标记这个安全?事实并非如此.如果没有HTML转义,格式化参数中的任何HTML特殊字符都可能导致HTML注入漏洞导致XSS攻击.你的撇号也是错误的:

"alt='{1}\'s profile'"
Run Code Online (Sandbox Code Playgroud)

\'是一个Python字符串文字转义; 你将返回字符串:

alt='someone's profile'
Run Code Online (Sandbox Code Playgroud)

这意味着你永远不会看到'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))
Run Code Online (Sandbox Code Playgroud)