从表字段中选择不同的值

alj*_*alj 89 django django-orm django-queryset query-performance

我正在努力绕过Django的ORM.我想要做的是在我的表格中的字段中获取不同值的列表....相当于以下之一:

SELECT DISTINCT myfieldname FROM mytable
Run Code Online (Sandbox Code Playgroud)

(或者)

SELECT myfieldname FROM mytable GROUP BY myfieldname
Run Code Online (Sandbox Code Playgroud)

在使用原始sql之前,我至少喜欢用Django方式做.例如,使用表格:

id,街道,城市

1,赫尔大街

2,其他街,赫尔

3,Bibble Way,莱斯特

4,另一种方式,莱斯特

5,高街,Londidium

我想得到:

船体,莱斯特,Londidium.

juj*_*ule 179

说你的模特是'商店'

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')
Run Code Online (Sandbox Code Playgroud)

由于您可能设置了Metaclass ordering属性,因此您可以在order_by()不使用参数的情况下使用它来清除任何顺序distinct().请参阅()下的文档order_by

如果您不希望将任何排序应用于查询,甚至不需要默认排序,请调用order_by(),不带参数.

distinct()在说明中讨论了distinct()与订购一起使用的问题.

要查询您的数据库,您只需要致电:

models.Shop.objects.order_by().values('city').distinct()
Run Code Online (Sandbox Code Playgroud)

它返回一个字典

要么

models.Shop.objects.order_by().values_list('city').distinct()
Run Code Online (Sandbox Code Playgroud)

这个返回一个ValuesListQuerySet你可以强制转换为list.您还可以添加flat=Truevalues_list扁平化的结果.

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

  • 其实这很有效.然而!我无法让它在我的所有模型上工作.Weidly,它在一些但不在其他方面工作.对于那些有Meta排序的人,它不起作用.因此,您必须首先清除查询集的顺序.models.Shop.objects.order_by().值( '城市').不同的() (27认同)
  • `values_list`返回ValuesListQuerySet,它是一个迭代器.转换为列表可能很方便,但是当必须一次评估所有行时,尤其是对于大型数据集,也可以提高性能. (8认同)
  • django orm和`objects.distinct()`与`objects.ordering().distinct()`的`Meta:ordering =()`"feature"引起了我们数小时的困惑.该产品应该有一个消费者安全警告标签;)我们可能会制定一个无元订购属性的政策,以防止将来头疼. (3认同)
  • 值得注意的是,`values_list`实际上并不返回列表.它返回类似于查询集的内容.我发现总是在values_list调用周围使用list()很有用. (2认同)

ing*_*yer 6

除了jujule仍然非常相关的答案外,我发现还很重要的一点是,也要意识到jujuleorder_by()distinct("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')  
Run Code Online (Sandbox Code Playgroud)