考虑区域设置的排序列表(瑞典排序)

时间:2012-03-03 14:23:27

标签: python django postgresql locale

显然PostgreSQL 8.4和Ubuntu 10.04无法处理瑞典字母表中W和V排序的更新方式。也就是说,它仍然将它们命名为相同的字母(瑞典订购的旧定义):

  • Vb的
  • WC
  • Vd的

应该是(瑞典订购的新定义):

  • Vb的
  • Vd的
  • WC

我需要为我正在构建的Python / Django网站正确订购。我已经尝试了各种方法来使用* values_list *来命令从Django QuerySet创建的元组列表。但由于它是瑞典语,ä,ä和ö字母需要正确订购。现在,无论是两种方式还是其他方式都不是......

list_of_tuples = [(u'Wa', 1), (u'Vb',2), (u'Wc',3), (u'Vd',4), (u'Öa',5), (u'äa',6), (u'Åa',7)]

print '########## Ordering One ##############'
ordered_list_one = sorted(list_of_tuples, key=lambda t: tuple(t[0].lower()))
for item in ordered_list_one:
    print item[0]

print '########## Ordering Two ##############'
locale.setlocale(locale.LC_ALL, "sv_SE.utf8")
list_of_names = [u'Wa', u'Vb', u'Wc', u'Vd', u'Öa', u'äa', u'Åa']
ordered_list_two = sorted(list_of_names, cmp=locale.strcoll)
for item in ordered_list_two:
    print item

示例给出:

########## Ordering One ##############
Vb
Vd
Wa
Wc
äa
Åa
Öa
########## Ordering Two ##############
Wa
Vb
Wc
Vd
Åa
äa
Öa

现在,我想要的是这些的组合,以便V / W和å,ä,ö的排序是正确的。更确切地说。我想订购一个来尊重语言环境。然后在每个元组中使用第二个项(对象id),我可以在Django中获取正确的对象。

我开始怀疑这是可能的吗?是否可以将PostgreSQL升级到更好的版本,更好地处理整理,然后在Django中使用原始SQL?

2 个答案:

答案 0 :(得分:8)

在Ubuntu-10.04上运行LC_ALL=sv_SE.UTF-8 sort示例时,它会在Vb之前出现Wa(“旧方式”),因此Ubuntu似乎不同意“新方式”。 由于PostgreSQL依赖于操作系统,因此它的行为与给定相同lc_collat​​e的操作系统相同。

debian glibc实际上有一个与此特定排序问题相关的补丁: http://sourceware.org/bugzilla/show_bug.cgi?id=9724 但它遭到反对而不被接受。如果您在所管理的系统上只需要此行为,则仍可以将修补程序的更改应用于/ usr / share / i18n / locales / sv_SE,并通过运行locale-gen sv_SE.UTF-8来重建se_SV语言环境。或者更好的是,创建自己的替代语言环境,以避免弄乱原语。

答案 1 :(得分:0)

这个解决方案很复杂,因为key = locale.strxfrm工作正常 使用单个列表和词典,但不包含列表或列表 元组列表。

Py2的变化 - > Py3:使用locale.setlocale(locale.LC_ALL,'') 和key ='locale.strxfrm'(而不是'cmp = locale.strcoll')。

list_of_tuples = [('Wa', 1), ('Vb',2), ('Wc',3), ('Vd',4), ('Öa',5), ('äa',6), ('Åa',7)]

def locTupSorter(uLot):
    "Locale-wise list of tuples sorter - works with most European languages"
    import locale
    locale.setlocale(locale.LC_ALL, '') # get current locale

    dicTups = dict(uLot)          # list of tups to unsorted dictionary
    ssList = sorted(dicTups, key=locale.strxfrm)
    sLot = []
    for i in range(len(ssList)):  # builds a sorted list of tups 
        tfLot = ()
        elem = ssList[i]          # creates tuples for list
        tfLot = (elem, dicTups[elem])
        sLot.append(tfLot)        # creates sorted list of tuples
    return(sLot)


print("list_of_tuples=\n", list_of_tuples)
sortedLot = locTupSorter(list_of_tuples)
print("sorted list of tuples=\n",sortedLot)