我正在构建一个应用程序,该应用程序在数据库中包含带有拉丁符号的数据。用户可以输入这些数据。到目前为止,我一直在做的是在模板中显示数据时在最后对每个用户输入进行编码('latin2')和解码('latin2')。这有点烦人,我想知道是否有更好的方法来处理这个问题。
2 回答
Python 的unicode
类型被设计为字符串的“自然”表示。除了unicode
类型之外,字符串应该是一些未指定的编码,但是没有办法用使用的编码“标记”它们,python 会非常坚持地假设字符串是 ASCII 或 UTF-8 编码。因此,如果您编写整个程序来假设这str
意味着 latin2,您可能会感到头疼。编码问题会潜入代码中的奇怪位置并渗透到各个层,有时会在数据库中获取错误数据,并最终在完全不相关且无法调试的地方导致奇怪的行为或令人讨厌的错误。
我建议您查看有关将您的数据库数据转换为 UTF-8 的信息。
如果您不能这样做,我强烈建议您将编码/解码调用移动到您将数据传输到/从数据库传输的那一刻。如果您有任何类型的数据库抽象层,您可能可以将其配置为或多或少地自动为您处理。然后,您应该确保任何用户输入都立即转换为unicode
类型。
以这种方式使用unicode
类型和显式编码/解码还有一个优点,即如果您确实遇到编码问题,您可能会更快注意到,您可以将unicode-nazi扔给他们以追踪它们(请参阅如何制作 python 2.x将字符串强制转换为 unicode 时发出警告?)。
对于您的标记问题:Flask 和 Jinja2 默认情况下会在将字符串中的任何不安全字符呈现到 HTML 之前对其进行转义。要覆盖自动转义,只需使用
safe
过滤器:
<h1>More than just text!</h1>
<div>{{ html_data|safe }}</div>
有关详细信息,请参阅Flask 模板:控制自动转义,并非常小心地使用它,因为您正在有效地从数据库加载代码并执行它。在现实生活中,您可能想要清理数据(请参阅Python HTML sanitizer/scrubber/filter或Jinja2 转义除 img、b 等之外的所有 HTML)。
尝试将此添加到程序的顶部。
import sys
reload(sys)
sys.setdefaultencoding('latin2')
我们必须重新加载 sys 因为:
>>> import sys
>>> sys.setdefaultencoding
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'setdefaultencoding'
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding
<built-in function setdefaultencoding>