j0k*_*ker -1 python django encoding
我是德国开发人员,为德国人编写Web应用程序,这意味着我无论如何都不能依赖纯ASCII编码.至少必须支持像ä,ö,ü,ß这样的字符.
幸运的是,Django默认将ByteStrings视为utf-8编码(如文档中所述).所以它应该工作,如果我将# -*- coding: utf-8 -*-行添加到每个.py文件的开头并设置编辑器编码,不应该吗?好吧,它大部分时间都在......
但是当涉及到URL时,我似乎错过了一些东西.或者也许这不会对URL做任何事情,但直到现在我还没有注意到任何其他编码错误行为.我记得有两种情况作为例子:
URL模式url(r'^([a-z0-9äöüß_\-]+)/$', views.view_page)无法识别包含ä,ö,ü,ß的网址.这些字符被简单地忽略了.
以下代码的视图函数抛出异常:
def do_redirect(request, id):
return redirect('/page/{0}'.format(id))
Run Code Online (Sandbox Code Playgroud)
从URL中捕获id参数,如第一个示例中的那个.如果我修复了URL模式(通过将其指定为unicode字符串)而不是访问/ä/,我得到了Exception
UnicodeEncodeError at /ä/
'ascii' codec can't encode character u'\xe4' in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
但是,为视图函数尝试以下代码:
def do_redirect(request, id):
return redirect('/page/' + id)
Run Code Online (Sandbox Code Playgroud)
一切都很好.这让我相信实际问题不在于Django,而是源自Python,将ByteStrings视为ASCII.我对编码没那么多,但第二个例子中的问题显然是String对象的format()方法.所以,在第一个例子中,由于Python处理正则表达式的方式,它可能会失败(虽然我不知道Django是否使用了re模块或其他东西).
到目前为止,我的解决方法只是在u发生此类错误时为字符串添加前缀.这是一个糟糕的解决方案,因为我可能很容易忽略一些东西 我尝试将每个Python字符串标记为unicode,但这会导致其他异常并且非常难看.
有没有人确切地知道,问题是什么以及如何以愉快的方式解决它(即当代码变大时不会让你的头爆炸的方式)?
提前致谢!
编辑:我的正则表达式,我发现,为什么u需要.将字符串指定为Raw String(r)使其被解释为ASCII.离开r之后使正则表达式工作没有u但是引入了一些带有反斜杠的头痛.
使用前缀u来解决问题.
如果它对你来说是一个问题,那么它看起来像是一个更普遍的问题的症状:你的代码中有很多魔术常量.这很糟糕(你已经明白了原因).尽量避免使用它们,例如,您可以使用命名的url模式或视图名称进行重定向,而不是重新键入URL的一部分.
如果无法避免它们,请将它们转换为命名常量,并将其分配放在一个位置.然后,你会发现所有这些都是正确的前缀,很难忽视它.