2012-03-11 58 views
-1

我是德国开发人员,为德国人编写Web应用程序,这意味着我无法通过任何方式依赖纯ASCII编码。至少需要支持ä,ö,ü,ß等字符。在Django中,为什么我会遇到utf-8编码字符串的问题?

幸运的是,Django的对待字节串为UTF-8编码的默认(如所描述的in the docs)。所以它应该可以工作,如果我将# -*- coding: utf-8 -*-行添加到每个.py文件的开头并设置编辑器编码,不是吗?嗯,它大部分时间都是这样的......

但是,在网址方面,我似乎错过了一些东西。或者,也许这并没有对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字符串),比访问/ä/,我得到的异常

UnicodeEncodeError at /ä/ 
'ascii' codec can't encode character u'\xe4' in position 0: ordinal not in range(128) 

然而,试图为视图功能如下代码:

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的情况下工作,但引入了一些反斜线的头痛。

+1

“这是一个糟糕的解决方案,因为我可能很容易忽略某些东西。”嗯,不,这就是*解决方案。 – 2012-03-11 13:02:20

+0

我的问题是,我不知道哪些字符串是危险的,因为我不知道他们为什么失败。它确实有效,但我永远不能说我是否阻止了所有潜在的编码错误。所以,这是一个糟糕的解决方案_for me_;) – j0ker 2012-03-11 13:10:28

+0

这就是python现在的工作方式。 Python3将有望解决这些问题。 – 2012-03-11 13:24:45

回答

5

使用u为字符串添加前缀是解决方案。

如果这是你的问题,那么它看起来像一个更一般的问题的症状:您在代码中有很多magic constants。这是不好的(你已经看到了为什么)。尽量避免它们,例如,您可以使用​​进行重定向,而不是重新输入URL的部分。

如果无法避开他们,把他们变成命名常量,并将其分配在同一个地方。然后,你会发现它们都是正确的前缀,很难忽略它。

+0

感谢您的提示。命名的网址模式是我所需要的。 – j0ker 2012-03-11 17:11:39

1

在django 1.4中,其中一个新功能是更好地支持url internationalization,包括支持翻译URL。

这将帮助你走出很长的路,但这并不意味着你应该忽略其他建议,因为它适用于所有Python,并且适用于所有内容,而不仅仅是django。