2009年2月26日星期四

Django 中的转义--escape

django字符串分为三类:
1. raw strings: 原始的python字符串或unicode字符串;如果auto-escaping(自动转义)起作用,则字符串被转义,否则不做改变输出;
2. safe strings: 被标记为安全的字符串,以免在输出时被转义,一般被用于含有原始html标记字符串的输出;
from django.utils.safestring import SafeData
if isinstance(value, SafeData):
.................
3. needing escaping strings: 需要转义的字符串,在输出的时候经常被转义,不论是否auto-escaping已经启用,即使auto-escaping启用,字符串都只被转义一次。 needing escaping strings 主要是为了转义过滤器执行而存在。

template 过滤分为两种情况:
1. 自定义的过滤器不产生任何不安全的html标记到输出结果中,在这种情况下,可以让django解决自动转义问题。需要
设置自定义过滤器的“is_safe"属性为True,譬如:
@register.filter
def myfilter(value):
return value
myfilter.is_safe = True
is_safe=True告诉django过滤器是安全的,如果输入字符串为True则输出字符串是安全的,否则django
将自动转义。如果template启用auto-escaping,则无论输入字符串是否标记为safe,输出字符串都会被
转义。
2. 另外,过滤器能手工管理任何必要的转义,特别是当需要在输出中产生新的html标记,或者需要标记输出结果为safe,以免在输出时被转义,这样输出结果中包含的html标记就不会再被转义了。要想标记输出为safe字符串,使用django.utils.safestring.mark_safe(),不过需要确定其确实是安全的。如果想知道目前auto-escaping的状态,在过滤器中设置needs-autoescape属性为True,这样告诉django过滤器
需要传递一个关键参数:autoescape,此变量如果为True,则autoescape被启用。

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

以上例子中,输出结果被标记为safe,这样可以直接插入到template中,而不会被转义。

3. template safe
去掉template的autoescape可以使用safe过滤器,也可使用autoescape标签,还可修改render的autoescape属性。
使用safe filter:

This will be escaped: {{ data }}

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

4. 使用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继承。

5. 修改Context类的autoescape属性:
def render(self, context):
# …
new_context = Context({‘var’: obj}, autoescape=context.autoescape)
注:autoescape标签的优先级高于Context类的autoescape属性,即如果Context中autoescape设置与模板中autoescape标签冲突,则使用autoescape标签的autoescape设置值。

6、使用方法函数mark_safe
使用mark_safe函数标记后,django将不再对该函数的内容进行转义。

没有评论: