在Django中,为什么utf8编码的字符串会出现问题?

用户

我是一个为德国人编写web应用程序的德国开发人员,这意味着我无论如何都不能依赖于纯ASCII编码。至少像ä,ö,ß这样的角色必须得到支持。在

幸运的是,Django将ByteStrings视为默认编码的utf-8(如in the docs所述)。因此,如果我在每个.py文件的开头添加# -*- coding: utf-8 -*-行并设置编辑器编码,它应该可以正常工作,不是吗?嗯,大多数时候都是这样。。。在

但我似乎错过了一些关于网址的东西。或许这与url没有任何关系,但直到现在我还没有注意到任何其他的编码错误行为。我记得有两个例子:

URL模式url(r'^([a-z0-9äöüß_\-]+)/$', views.view_page)根本不识别包含ä,ö,ü,ß的URL。这些字符被忽略了。在

视图函数的以下代码引发异常:

def do_redirect(request, id):
    return redirect('/page/{0}'.format(id))

其中id参数是从URL捕获的,就像第一个示例中的参数一样。如果我修复了URL模式(通过将其指定为unicode字符串),然后访问/ä/,我会得到异常

^{pr2}$

但是,请尝试对view函数执行以下代码:

def do_redirect(request, id):
    return redirect('/page/' + id)

一切都很顺利。这让我相信真正的问题不在Django内部,而是源于Python,将ByteStrings当作ASCII处理。我不太喜欢编码,但第二个例子中的问题显然是String对象的format()方法。因此,在第一个示例中,它可能会失败,因为Python处理正则表达式的方式(尽管我不知道Django是否使用re模块或其他东西)。在

到目前为止,我的解决方法只是在出现这样的错误时在字符串前面加上u。这是一个糟糕的解决办法,因为我很容易忽略一些事情。我尝试将每个Python字符串标记为unicode,但这会导致其他异常,而且非常难看。在

有没有人确切地知道问题是什么,以及如何以一种愉快的方式解决它(即,当代码变大时,不会让你的脑袋爆炸的方法)?在

提前谢谢!在

编辑:对于我的正则表达式,我发现了为什么需要u。将字符串指定为原始字符串(r)会使其被解释为ASCII。离开r会使正则表达式在没有u的情况下工作,但是反斜杠会带来一些麻烦。在


已被浏览了8932次
更新日期: 2020-10-28 20:08:07
2 个回答
fefe Tyson

在django1.4中,新特性之一是更好地支持url internationalization,包括对转换url的支持。在

这在很大程度上有助于您解决问题,但这并不意味着您应该忽略其他建议,因为这通常适用于Python,适用于所有,而不仅仅是django。在

评论 - 2020年8月7日 23:13
fefe Tyson

在字符串前面加上u就是解决方案。在

如果这对您来说是个问题,那么它看起来像是一个更普遍的问题的症状:您的代码中有很多{a1}。这很糟糕(你已经知道原因了)。尽量避免它们,例如,可以使用named url pattern or view name进行重定向,而不是重新键入URL的部分。在

如果无法避免它们,请将它们转换为命名常量,并将它们的赋值放在一个位置。然后,您将看到它们都有正确的前缀,很难忽略它。在

评论 - 2020年8月7日 23:13

最新Python问答

推荐Python问答