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
,这似乎也无济于事。
答案 0 :(得分:1)
我维护了内联应用的a fork。 Richard和我联系了这个问题,我能够追溯到BeautifulSoup,而不是Django。
问题在于,使用BeautifulSoup的replaceWith()
方法将内联标记替换为渲染模板。 render_to_string()
的结果当然是一个字符串。当replaceWith()
收到字符串时,会将其转换为NavigableString
。由于BeautifulSoup期望NavigbleString
是字符串,因此它假定它们不安全并且转义任何HTML字符。结果是,Inline的inlines()
函数返回的值中包含>
和<
,而不是<
和>
。
我没有在Django 1.3中注意到这个问题。当我看,BeautifulSoup确实返回了转义的HTML。 Django的|safe
模板过滤器必须取消以前转义的HTML。在Django 1.4中,它不再那样做了。 (它不应该这样做!)
我对此的修复是使用BeautifulSoup解析传入的值并使用BeautifulSoup查找所有内联标记,就像之前一样。而不是使用BeautifulSoup的replaceWith()
方法用渲染的内联模板替换内联标记,我现在只使用Python的普通旧str.replace()
。对我来说感觉有点蹩脚,将解析后的汤转换回字符串,然后进行字符串替换。但它的确有效。我部分想要完全取消BeautifulSoup并找到带有正则表达式的内联标记但we all know how that ends。如果有人有更好的想法,我全都听见了!
该修复最初是在this commit中实现的。我在下面的提交中改进了它,但显然StackOverflow只允许我发布最多两个链接,所以你必须自己找到它!
答案 1 :(得分:1)
另一个解决方案是将新代码转换为BeautifulSoup对象,并替换为所述对象。这样美丽的汤似乎表现得正确。
这为你提供了转义html:
soup = BeautifulSoup(html_doc)
body = soup.body
new_html = """<p> this is some deap code</p><a href="#">Pointless even</a>"""
body.replaceWith(new_html)
这为您提供了未经证实的html:
soup = BeautifulSoup(html_doc)
body = soup.body
new_html = """<p> this is some deap code</p><a href="#">Pointless even</a>"""
body.replaceWith(BeautifulSoup(new_html))
答案 2 :(得分:0)
这是因为render_to_string
here。转到inlines/app_model.html
和inlines/default.html
,然后在内容变量之后添加|safe
。