142

我正在努力理解 Django 的 ORM。我想要做的是在我的表上的一个字段中获取不同值的列表....相当于以下之一:

SELECT DISTINCT myfieldname FROM mytable

(或替代)

SELECT myfieldname FROM mytable GROUP BY myfieldname

在诉诸原始 sql 之前,我至少想以 Django 方式进行操作。例如,有一个表:

身份证,街道,城市

1,主街,赫尔

2,其他街,赫尔

3,圣经之路,莱斯特

4,另一种方式,莱斯特

5, 高街, 朗迪迪姆

我想得到:

赫尔、莱斯特、朗迪迪姆。

4

4 回答 4

268

假设您的模型是“商店”

class Shop(models.Model):
    street = models.CharField(max_length=150)
    city = models.CharField(max_length=150)

    # some of your models may have explicit ordering
    class Meta:
        ordering = ('city',)

由于您可能设置了Metaordering属性(元组或列表),因此您可以order_by()在使用distinct(). 请参阅()下的文档order_by

如果您不希望将任何排序应用于查询,即使是默认排序也不行,请不带参数调用 order_by()。

distinct()在讨论distinct()与订购一起使用的问题的注释中。

要查询您的数据库,您只需调用:

models.Shop.objects.order_by().values('city').distinct()

它返回一个字典

或者

models.Shop.objects.order_by().values_list('city').distinct()

这个返回 a ValuesListQuerySet,您可以将其转换为 a list。您还可以添加flat=Truevalues_list以展平结果。

另请参阅:按字段获取 Queryset 的不同值

于 2010-03-18T09:23:19.740 回答
21

除了jujule 仍然非常相关的答案之外order_by(),我发现了解ondistinct("field_name")查询的含义也很重要。然而,这是 Postgres 独有的功能!

如果您使用的是 Postgres,并且如果您定义了查询应该不同的字段名称,则order_by()需要以相同的顺序以相同的字段名称(或多个字段名称)开头(之后可能会有更多字段)。

笔记

指定字段名称时,必须在 QuerySet 中提供 order_by(),并且 order_by() 中的字段必须以 distinct() 中的字段开头,顺序相同。

例如,SELECT DISTINCT ON (a) 为您提供 a 列中每个值的第一行。如果你不指定一个顺序,你会得到一些任意的行。

如果你想提取一个你知道商店的城市列表,jujule 的例子必须适应这个:

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  
于 2018-05-24T07:31:10.780 回答
2

举例:

# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []
于 2018-08-06T01:33:57.140 回答
0

如果您使用PostgreSQL,而只想使用一个可以使用的特定字段来获取和区分

MyModel.objects.values('name').annotate(Count('id')).order_by()

此查询集返回我们的行,它们的“名称”字段是唯一的,具有相同名称的行的计数

<QuerySet [{'name': 'a', 'id__count': 2}, {'name': 'b', 'id__count': 2}, {'name': 'c', 'id__count': 3}>

我知道返回的数据不完整,有时并不令人满意,但有时它很有用

文件参考

于 2022-01-05T20:43:48.640 回答