如何防止Django基本内联自动转义
问题内容:
Django Basic Inlines应用基于app / model /
id组合从伪HTML语法呈现预定模板。例如,如果您正在写博客文章,则可以插入保存在图像模型中的图像:
# In the admin
This is the body of my post.
<inline type="media.image" id="1" class="full">
然后,模板将使用一个render_inlines
过滤器,该过滤器需要进行标记safe
以正确呈现HTML:
# Template
{{ post.body|render_inlines|safe }}
但是即使使用safe
,过滤器仍会转义HTML,而是<p><img src="..."><p>
在源代码中创建。
根据文档,过滤器应使用mark_safe
来防止在过滤器级别自动转义,但是该inlines
功能parser.py
已经使用mark_safe
。
Django 1.4中是否还需要其他一些东西来停止在自定义滤镜层自动转义?我似乎无法摆脱这种自动转义,无论是在
我尝试使用autoescape=None
,但似乎也无济于事。
问题答案:
我维护Inline应用程序的分支。理查德就此问题与我联系,我能够将其追溯到BeautifulSoup,而不是Django。
问题在于,BeautifulSoup的replaceWith()
方法被用来用呈现的模板替换内联标记。结果render_to_string()
当然是一个字符串。当replaceWith()
接收到一个字符串,它把它变成一个NavigableString
。由于BeautifulSoup期望NavigbleString
s是字符串,因此假定它们是不安全的,并且转义了任何HTML字符。结果是Inlineinlines()
函数返回的值中有一堆>
and<
而不是<
and
>
。
我在Django
1.3中没有注意到这个问题。当我看时,BeautifulSoup确实返回了转义的HTML。Django的|safe
模板过滤器必须已经转义了先前转义的HTML。在Django
1.4中,它不再这样做。(它不应该这样做!)
我的解决方法是像以前一样,使用BeautifulSoup解析传入的值,并使用BeautifulSoup查找所有内联标记。而不是使用BeautifulSoup的replaceWith()
方法用呈现的内联模板替换内联标记,我现在仅使用Python的old
str.replace()
。对我来说有点la脚,将解析的汤转换回字符串,然后进行字符串替换。但这有效。我有部分打算完全放弃BeautifulSoup,并找到具有正则表达式的内联标记,但是我们都知道那怎么结束。如果有人有更好的主意,我全都听!
该修复程序最初是在此提交中使用的。我在以下提交中对其进行了改进,但是显然StackOverflow只允许我最多发布两个链接,因此您必须自己找到一个链接!