【问题标题】:Django request with unicode strings wrongly UTF-8 encoded带有 unicode 字符串的 Django 请求错误地 UTF-8 编码
【发布时间】:2012-10-28 14:37:08
【问题描述】:

我在使我的网站与重音字符兼容时遇到了一些问题(法语网站)。

我有一个表单,其中一些字段值可以带有重音字符:例如“Coupé”。

我的网址如下所示:

http://localhost:8080/recherches/s?marque=Audi&modeles=A5+Coup%C3%A9

在我的 django 视图中,我执行以下操作:

def search(request):
  logger = logging.getLogger('custom')
  criteria_form = CriteriaForm(request.GET or None)
  logger.debug("search")
  logger.debug(request.GET)

我在日志中得到的是:

<QueryDict: {u'marque': [u'Audi'], u'modeles': [u'A5 Coup\xc3\xa9']}>

如果我用这个变量“modeles”查询我的数据库,我会得到一个错误:

>>> mo = u'A5 Coup\xc3\xa9'
>>> Vehicule.objects.filter(valid=True, modele=mo)[0].marque.name
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 211, in __getitem__
    return list(qs)[0]
IndexError: list index out of range

如果我使用 utf-8 版本查询数据库,一切正常:

>>> mo = 'A5 Coup\xc3\xa9'
>>> Vehicule.objects.filter(valid=True, modele=mo)[0].marque.name
u'Audi'

所以我认为(但我可能错了)我的问题来自于我的变量是 utf8 然后用 unicode 编码的事实。

这是怎么编码的?

第一次回复后更新:

在发送表单的页面的标题上有:

<meta http-equiv="Content-type" content="text/html;charset=UTF-8"/>

但是,如果我在 views.py 中打印编码:

logger.debug(request.encoding)

然后我得到无。

但我不知道如何设置此编码。我以为它会像我上面所做的那样来自标题......

我的 HTTP_ACCEPT_CHARSET 中也有这个:

HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.3

可以从这里来吗?如果是,我应该如何改变它?

【问题讨论】:

  • 我更新了上面的帖子。我以为它是用 UTF-8 编码的,但是当我在 django views.py 中检查 request.encoding 时,我得到 None ...我不知道如何设置这种编码:/

标签: django unicode


【解决方案1】:

所有的验证魔法都在​​后台发生,绕过这一切可能更容易查明问题。在您看来,以下产生了什么?

Vehicule.objects.filter(valid=True, modele=request.GET['mo'])[0].marque.name

如果您所做的只是传递一个查询,那么在您取回值之前,您庞大的 Ajaxariffic 验证集将对您的 unicode 进行奇怪的 Python 操作,并可能最终敲掉您的特殊字符。

编辑:在我自己玩过这个之后,看起来 GET 中的 urlified 数据是问题所在。与其使用 string.encode('iso8859-1').decode('utf8'),不如更轻松地更改表单以提交 POST 数据并使用它。

【讨论】:

  • 如果我这样做,我会遇到同样的问题。我从 dB 中得到一个错误,说列表索引超出范围。因为 request.GET['mo'] 格式错误。如果我记录它包含:A5 Coupé... 不在数据库中...
  • 在进一步播放后编辑。
【解决方案2】:

我终于找到了问题所在。我用一个几乎没有任何内容的全新 django 应用程序测试了这个问题。没有 DB,一个简单的视图,在页面中显示表单的内容。 像这样的:

# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext


def test(request):
  found = request.GET.get('modeles')
  print found
  return render_to_response('test.html',
                            {"found":found},
                            context_instance=RequestContext(request))

如果我打开网址

localhost:8080/mysite?modeles=Coupé

我得到了格式错误的 Coupé

在这里,我当然不能责怪任何 ajax、db 调用或我可以在 python 中完成的任何事情。

所以我只是在 Django 1.4 上进行了尝试......它就像一个魅力! 然后我尝试了最新的 Django 1.5a1 版本,它也可以工作......

我想我现在不应该使用测试版。我会坚持 1.4!

希望这可以为其他人节省时间。

【讨论】:

    猜你喜欢
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    相关资源
    最近更新 更多