Django不区分大小写的“distinct”查询

8

我正在使用这个Django查询

people.exclude(twitter_handle=None).distinct('twitter_handle').values_list('twitter_handle', flat=True)

我的查询结果返回了两个对象。例如:

['Abc','abc']

如何获得不区分大小写的结果?就像在这种情况下一样。
['abc']

使用django 1.9.6, python 2.7。
2个回答

5
你可以使用.annotate()Func()表达式来在小写的twitter_handle值上应用.distinct()
>>> from django.db.models.functions import Lower
>>> people.order_by().exclude(twitter_handle=None).annotate(handle_lower=Lower("twitter_handle")).distinct("handle_lower")

由于您无法在values_list('twitter_handle', flat=True)查询中应用distinct,因为您无法在values_list中应用不存在的字段,所以您需要自行完成此操作:

 >>> queryset = people.order_by().exclude(twitter_handle=None).annotate(handle_lower=Lower("twitter_handle")).distinct("handle_lower")
 >>> [p.twitter_handle for p in queryset]

或者你可以获取小写的twitter_handle值:

>>> people.order_by().exclude(twitter_handle=None).annotate(handle_lower=Lower("twitter_handle")).distinct("handle_lower").values_list("handle_lower", flat=True)

@Ozagur Vatansever,实际上我正在处理一个非常庞大的数据集,注释会不会在查询中增加额外的步骤? - Daniyal Syed
是的,这可能会增加执行时间的开销,因为您在非索引字段上应用了distinct。您可以为“LOWER(twitter_handle)”字段定义一个索引来克服这个问题。如果您正在使用PostgreSQL,则可以按照以下步骤操作:https://www.postgresql.org/docs/9.3/static/indexes-expressional.html - Ozgur Vatansever
@Ozagur Vatansever,是的,我正在使用PostgreSQL,谢谢,我一定会尝试的。 - Daniyal Syed

0
一个解决方案是使用 annotate 创建一个新字段并附带小写值,然后对其使用 distinct
尝试类似以下的东西:
from django.db.models.functions import Lower

(people.exclude(twitter_handle=None)
      .annotate(handle_lower=Lower('twitter_handle'))
      .distinct('handle_lower'))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接