在django查询中处理外来字符

时间:2012-01-23 06:08:59

标签: python django internationalization

我正在搜索从GeoNames.com导入的城市名称。一些城市的名字中有国际字符。例如,“伊斯坦布尔”实际上是数据库中的“İstanbul”。

当人们搜索“伊斯坦布尔”时,伊斯坦布尔不会出现。

有没有办法可以在搜索中添加过滤器或解码器,以便知道İstanbul= Istanbul

目前,它是:

cities = City.objects.filter(name__icontains=query)

4 个答案:

答案 0 :(得分:3)

Unidecode将帮助您解决某种形式的此问题。 Unidecode会将非ascii字符转换为ascii,例如:

>>> from unidecode import unidecode
>>> unidecode(u"İstanbul")
'Istanbul'

您可以通过分解unicode字符并删除组合变音符来实现类似的效果。此技术的问题是某些字符不可分解。因此,虽然“ö”将分解为“o”和变音符号,但“Ł”(L-stroke)将保持不变。 Unidecode成功将“Ł”翻译为“L”。

但是Undeicode并没有解决你所有的问题;城市可以用不同的名称来识别,或者这些名称可以用不同的名称来表示。例如,在美国,我们将中国的首都称为“北京”,但过去我们称其为“北京”(瑞典语中称为“Peking”),并将其名称翻译为unidecode给我们一些东西否则:

>>> unidecode(u"\u5317\u4EB0")
'Bei Jing '

最好的解决方案是拥有一个特定于语言的名称列表,而不是使用该城市的实际名称。

答案 1 :(得分:1)

我认为django没有为它准备好的东西。

我会在数据库中创建一个名为NameCombinations的单独列,其中我将所有可能的组合放在一起,例如Istanbulİstanbul并将查询

cities = City.objects.filter(NameCombinations__icontains=query)

答案 2 :(得分:0)

如果没有关于你想要什么行为的更多信息,很难给出明确的建议。

然而,一个显而易见的步骤是为每个名称定义规范形式(小写,没有重音等),并将名称的规范形式存储在数据库的第二列中,此外还有正确的名称。然后将搜索字符串映射到规范形式。因此,“伊斯坦布尔”可能是“伊斯坦布尔”的规范形式。

另一个明显的步骤是将城市名称与其他有关城市的信息分开。这让每个城市都有几个名字,即同义词。然后,对于每个城市名称,根据需要定义尽可能多的同义词,以捕获用户喜欢的不同拼写。例如,您可以输入“Istanbul”和“イスタンブル”作为“İstanbul”的同义词。

您当然可以同时使用这两种方法。

答案 3 :(得分:-1)

在数据库中设置了适当的排序规则后,比较将完全按照您的意愿进行。