如何防止Django基本内嵌自动转义 [英] How to prevent Django basic inlines from autoescaping

查看:153
本文介绍了如何防止Django基本内嵌自动转义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Django Basic Inline应用程序基于app / model / id组合,从伪HTML语法呈现预定义的模板。例如,如果您正在撰写博客文章,则可以插入保存在图像模型中的图像:

The Django Basic Inlines app renders a pre-determined template from a pseudo-HTML syntax, based on an app/model/id combination. For example, if you're writing a blog post, you can insert an image that was saved in your image model:

# In the admin
This is the body of my post.

<inline type="media.image" id="1" class="full">

然后,该模板需要一个 render_inlines 这需要标记为 safe ,以便正确呈现HTML:

The template then takes a render_inlines filter, which requires to be marked safe so as to render the HTML properly:

# Template
{{ post.body|render_inlines|safe }}

但即使安全,过滤器仍然转义HTML,创建& lt; p& gt& lt; img src =...& ;< p& gt;

But even with safe, the filter still escapes the HTML, creating &lt;p&gt;&lt;img src="..."&gt;&lt;p&gt; in the source.

根据文档,过滤器应使用 mark_safe 以防止在过滤器级别进行自动转义,但 inlines 函数在 parser.py 已经使用 mark_safe

According to the docs, the filter should use mark_safe to prevent autoescaping at the filter level, but the inlines function in parser.py already uses mark_safe.

Django 1.4中还有一些需要在自定义中停止自动转义过滤层?我似乎无法摆脱这种自动转换,无论是在

Is there something that is further needed in Django 1.4 to stop autoescaping at the custom filter layer? I can't seem to get rid of this autoescaping, either at the

  • inlines function or the
  • render_inlines function.

code> autoescape = None ,这似乎也没有帮助。

I tried using autoescape=None, which didn't seem to help either.

推荐答案

我维护了Inline应用程序的一个叉子。理查德联系了我这个问题,我能够追溯到BeautifulSoup而不是Django。

I maintain a fork of the Inline app. Richard contacted me about this problem and I was able to trace it back to BeautifulSoup, not Django.

问题是,BeautifulSoup的 replaceWith() / code>方法被用来替换内置标记与渲染的模板。当然, render_to_string()的结果是一个字符串。当 replaceWith()接收一个字符串时,它将它变成一个 NavigableString 。由于BeautifulSoup希望 NavigbleString s是字符串,它假定它们是不安全的并且转义任何HTML字符。结果是Inline的 inlines()函数返回的值有一堆& gt; & lt; 而不是< >

The problem was that BeautifulSoup's replaceWith() method was being used to replace the inline markup with the rendered template. The result of render_to_string() is, of course, a string. When replaceWith() receives a string, it turns it into a NavigableString. Since BeautifulSoup expects NavigbleStrings to be strings, it assumes they are unsafe and escapes any HTML characters. The result is that the value being returned by Inline's inlines() function had a bunch of &gt; and &lt; in it rather than < and >.

Django 1.3中没有注意到这个问题。当我看到,BeautifulSoup确实是返回转义的HTML。 Django的 | safe 模板过滤器必须是先前转义的HTML。在Django 1.4中,它不再这样做了。 (而且它不应该这样做!)

I didn't notice this problem in Django 1.3,. When I looked, BeautifulSoup was indeed returning escaped HTML. Django's |safe template filter must have been unescaping the previously escaped HTML. In Django 1.4, it no longer does that. (And it shouldn't do that!)

我的解决办法是用BeautifulSoup解析传入的值,并使用BeautifulSoup查找所有的内联标记,就像以前一样。而不是使用BeautifulSoup的 replaceWith()方法来替换内置标记与渲染的内联模板,现在我只是使用Python的普通旧版 str.replace ()。感觉到我有点跛脚,将解析的汤转换成字符串,然后进行字符串替换。但它的作品。我部分地试图完全消除BeautifulSoup,并使用正则表达式找到内联标记,但我们都知道如何结束。如果有人有一个更好的主意,我都是耳朵!

My fix for this is to parse the incoming value with BeautifulSoup and use BeautifulSoup to find all the inline markup, just like before. Rather than using BeautifulSoup's replaceWith() method to replace the inline markup with the rendered inline template, I'm now just using Python's plain old str.replace(). It feels a bit lame to me, converting the parsed soup back to a string and then doing the string replacement. But it works. I'm partly tempted to just do away with BeautifulSoup altogether and find the inline markup with regular expressions but we all know how that ends. If anybody has a better idea, I'm all ears!

修复最初是在此提交。我在以下提交中改进了它,但显然StackOverflow只允许我发布最多两个链接,所以你必须自己找到那个!

The fix was initially implented in this commit. I improved it in the following commit, but apparently StackOverflow is only allowing me to post a maximum of two links, so you'll have to find that one yourself!

这篇关于如何防止Django基本内嵌自动转义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆