Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29335075
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Python/Ruby

2010-06-30 21:46:43

遇到django的转义问题,故查了些东西,来给大家一起分享:
原文转载自:


在此谢谢作者总结的很好!!!  

初次接触django的开发者,犯的一个常见错误就是转义。

何谓转义?就是把html语言的关键字过滤掉。例如,
就是html的关键字,如果要在html页面上呈现
,其源代码就必须是<div>
PS:转义其实就是把HTML代码给转换成HTML实体了!

默认情况下,django自动为开发者提供escape功能,即在html代码render之前,先进行转义,然后再呈现出来。这样的话,我们如果想输出一个链接,被转义之后,可能就无法得到我们想要的结果。

例如,下面的method,如果用户是匿名用户,则输出“匿名用户”,否则,输出一个链接,指向用户的profile:

def get_username(self):

       return “%s” %(self.user.id, self.user.username)



在template文件中,如果这样使用上面的方法:

{{topic.get_username}}

这样,输出的结果不是一个链接,而是上面链接转义后的原文。我们无法得到我们想要的结果。



有以下几种方法解决自动转义的问题:

1、filter中

修改filter函数的is_safe属性:

@register.filter

def myfilter(value):

    return value

myfilter.is_safe = True

如果你需要更复杂一些,可以亲自来处理escape属性。

首先,设置filter的need_autoesacpe属性为True(默认为False),这个参数告诉django,该filter需要一个传递一个autoesacape的参数,标示是否需要进行转义处理,如果为True,则转义,反之则反。完整的例子如下:



from django.utils.html import conditional_escape

from django.utils.safestring import mark_safe



def initial_letter_filter(text, autoescape=None):

    first, other = text[0], text[1:]

    if autoescape:

        esc = conditional_escape

    else:

        esc = lambda x: x

    result = ‘%s%s’ % (esc(first), esc(other))

    return mark_safe(result)

initial_letter_filter.needs_autoescape = True





2、template中

去掉template中的自动转义可以使用filter safe,也可以使用auotescape标签,还可以修改render的autoescape属性。

使用safe filter:

This will be escaped: {{ data }}

This will not be escaped: {{ data|safe }}



使用autoescape标签:

Auto-escaping is on by default. Hello {{ name }}



{% autoescape off %}

    This will not be auto-escaped: {{ data }}.



    Nor this: {{ other_data }}

    {% autoescape on %}

        Auto-escaping applies again: {{ name }}

    {% endautoescape %}

{% endautoescape %}

如果在autoescape的标签中include 其他的tags,autoescape的属性将被子tags继承。



修改Context类的autoescape属性:

def render(self, context):

    # …

       new_context = Context({‘var’: obj}, autoescape=context.autoescape)



注:autoescape标签的优先级高于Context类的autoescape属性,即如果Context中autoescape设置与模板中autoescape标签冲突,则使用autoescape标签的autoescape设置值。



>>> from django import template

>>> H=’{% autoescape off %}{{div}}{% endautoescape %}’

>>> c = template.Context({’div’:”
”}, autoescape=True)

>>> template.Template(H).render(c)

u’


>>>

>>> H=’{% autoescape on %}{{div}}{% endautoescape %}’

>>> c = template.Context({’div’:”
”}, autoescape=True)

>>> template.Template(H).render(c)

u’<div>’

>>> H=’{% autoescape on %}{{div}}{% endautoescape %}’

>>> c = template.Context({’div’:”
”}, autoescape=False)

>>> template.Template(H).render(c)

u’<div>’

>>>



3、使用方法函数mark_safe

使用mark_safe函数标记后,django将不再对该函数的内容进行转义,上面的get_username可以修改为:

from django.utils.safestring import mark_safe

def get_username(self):

       return mark_safe(”%s” %(self.user.id, self.user.username))
阅读(1239) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~