我有以下查询:
>>> z = Restaurant.objects.values_list('city',flat=True).order_by('city').distinct()
>>> z
[u'ELURU', u'Eluru', u'Hyderabad']
正如您所看到的,由于区分大小写,它并不完全不同。我该如何纠正这个问题?
答案 0 :(得分:4)
您可以将annotate与Lower(或更高等等)结合使用来规范化您的值并返回真正不同的值,例如...... < / p>
from django.db.models.functions import Lower
z = Restaurant.objects.annotate(
city_lower=Lower('city')).values_list(
'city_lower',flat=True).order_by('city_lower').distinct()
注意:确保 order_by 设置为&#39; city_lower&#39; ,而不是&#39; city&#39;避免重复。
答案 1 :(得分:1)
我不确定你是否会找到解决方案,因为django不提供不区分大小写的不同方法(目前)。但是,也许最好还是修改你的数据库中的值,因为你真的不希望你的最终用户在首都看到他们的城市,因为它看起来很难看。
我建议考虑制作一个简单的方法,您可以在数据迁移中运行一次,并停止城市字段再次进入此状态 - 或者只是定期运行。
类似于
for restaurant in Restaurant.objects.all():
if restaurant.city != restaurant.city.title():
restaurant.city = restaurant.city.title()
restaurant.save()
答案 2 :(得分:0)
试试这个;
z = Restaurant.objects.extra(select = {'tmp_city': lower('city')}).values_list('city',flat=True).order_by('city').distinct('tmp_city')
答案 3 :(得分:0)
这很有效,虽然有点乱。我最终不得不使用值,因为distinct只适用于数据库表,无论您是否使用annotate,extra或rawSQL。
您最终会创建一个带注释的额外字段,然后在由值创建的词典列表中使用该字段。拥有该词典列表后,您可以使用groupby根据词典值列表中的Lower values键对词典进行分组。然后,根据您希望如何选择对象(在这种情况下,只是获取组的第一个对象),您可以选择所需的distinct版本。
from django.db.models.functions import Lower
from itertools import groupby
restaurant = [g.next() for k, g in groupby(
list(
Restaurant.objects.annotate(city_lower=Lower('message_text')).values_list('city', flat=True)
).order_by('city').values('city_lower', 'city')
), lambda x: x['city_lower'])]