Django使用自定义排序规则进行查询

isk*_*rum 5 django collation

是否可以使用与数据库表不同的排序规则进行查询?

Pio*_*iek 10

使用extra()有点乱。现在可以使用Func()表达式实现类似的功能(自 Django 1.8 起):

username_ci = Func(
    'username',
    function='utf8_general_ci',
    template='(%(expressions)s) COLLATE "%(function)s"')
Run Code Online (Sandbox Code Playgroud)

这可以用于annotate()

User.objects.annotate(uname_ci=username_ci).filter(uname_ci='joeblow').exists()
Run Code Online (Sandbox Code Playgroud)

或者在order_by()排序时覆盖默认的排序规则:

User.objects.order_by(username_ci)
Run Code Online (Sandbox Code Playgroud)

现在,它看起来仍然很乱,但是如果您查看Func()的文档和代码,您会发现将其子类化并制作可重用的排序规则设置器非常容易。

我在 Postgres 数据库中使用了这个技巧。


小智 3

以下是如何对给定的表/列使用特定排序规则而不是默认排序规则。我假设您总是希望不区分大小写 utf8_general_ci,但您可以轻松地在代码中更改它或将其添加为变量。

请注意使用 params kwarg 而不是 db 文字函数。Params 的存在是出于完全相同的目的。

def iexact(**kw):
    fields = [['%s=%%s collate utf8_general_ci'%field,value] for (field,value) in kw.items()]
    return dict(where=[f[0] for f in fields], params=[f[1] for f in fields])

if User.objects.extra(**iexact(username='joeblow')).exists():
    status = "Found a user with this username!"
Run Code Online (Sandbox Code Playgroud)