【问题标题】:Django Query sort case-insensitive using Model method with PostgreSQLDjango Query 使用带有 PostgreSQL 的 Model 方法对大小写不敏感
【发布时间】:2013-12-25 04:06:43
【问题描述】:

我真的是 django、python 和 postgres 的新手......我似乎无法找到关于如何 order_by 在使用 Model 作为查询方法时不区分大小写的答案,只有当你使用直接 SQL 查询时。

Model
@classmethod
def get_channel_list(cls, account):
    return cls.objects.filter(accountid=account).order_by('-name').values_list('name', 'channelid')

当前排序的数据集和顺序

test
b test
a test channel
a test channel
a test 2 
a b test
Test Channel
Test 3
Test 3
Test 2 Channel

任何帮助将不胜感激。

【问题讨论】:

    标签: python django python-2.7 django-1.5 postgresql-9.3


    【解决方案1】:

    使用 django 1.8,有一个内置的解决方案:

    from django.db.models.functions import Lower
    ...
    ret = ret.order_by(Lower('name_lower'))
    ret = ret.order_by(Lower('name_lower').asc())
    ret = ret.order_by(Lower('name_lower').desc())
    

    【讨论】:

    • @Sven 如果我的问题不是专门针对 Django 1.5.3(而不是 1.8+),我会同意
    • 当您谈论仅对一列或多列在一个方向上进行排序时,此方法有效。但是,如果您需要对多个列进行排序,一些升序和一些降序呢? (例如,我选择 4 列,我希望它按 col 1 升序排序,其次按 col 3 降序)
    【解决方案2】:

    使用QuerySet.extra(select=...)

    @classmethod
    def get_channel_list(cls, account):
        ret = cls.objects.extra(select={'name_lower': 'lower(name)'})
        ret = ret.order_by('-name_lower')
        ret = ret.filter(accountid=account).values_list('name', 'channelid')
        return channels
    

    【讨论】:

    • 如果我这样做,我会收到以下错误Cannot resolve keyword 'name_lower' into field. Choices are: accountid, active, channelid, id, name
    • @AndrewWilson,您不需要向模型添加额外的字段。见this screencast我刚刚录制。
    • 由于某种原因,这在 Django 1.5.3 和 Python 2.7 中对我不起作用,不确定是否是版本问题
    • @AndrewWilson,在dbshell 中尝试select name from appname_modelname order by lower(name);。有用吗?
    • 它返回名称列表,而不以正确的顺序小写名称。使用 Postgresql 9.3
    猜你喜欢
    • 2017-10-14
    • 2016-11-15
    • 1970-01-01
    • 2023-03-27
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    相关资源
    最近更新 更多