120

我很好奇是否有任何方法可以在 Django 中进行查询,而不是SELECT * FROM...下面的“”。我正在尝试做一个“ SELECT DISTINCT columnName FROM ...”。

具体来说,我有一个看起来像这样的模型:

class ProductOrder(models.Model):
   Product  = models.CharField(max_length=20, promary_key=True)
   Category = models.CharField(max_length=30)
   Rank = models.IntegerField()

其中Rank是 a 中的等级Category。我希望能够遍历所有类别,对该类别中的每个等级进行一些操作。

我想首先获取系统中所有类别的列表,然后查询该类别中的所有产品并重复,直到处理完每个类别。

我宁愿避免使用原始 SQL,但如果我必须去那里,那很好。虽然我以前从未在 Django/Python 中编写过原始 SQL。

4

4 回答 4

219

从数据库中获取不同列名列表的一种方法是distinct()values().

在您的情况下,您可以执行以下操作来获取不同类别的名称:

q = ProductOrder.objects.values('Category').distinct()
print q.query # See for yourself.

# The query would look something like
# SELECT DISTINCT "app_productorder"."category" FROM "app_productorder"

这里有几件事要记住。首先,这将返回与 aValuesQuerySet行为不同的 a QuerySet。当你访问说,q(上面)的第一个元素你会得到一个字典,而不是一个实例ProductOrder

其次,阅读文档中有关使用distinct(). 上面的例子可以工作,但所有和的组合都distinct()可能values()不行。

PS :对模型中的字段使用小写名称是个好主意。在您的情况下,这意味着重写您的模型,如下所示:

class ProductOrder(models.Model):
    product  = models.CharField(max_length=20, primary_key=True)
    category = models.CharField(max_length=30)
    rank = models.IntegerField()
于 2010-10-04T05:30:09.720 回答
84

如果您使用的是 PostgreSQL,这实际上非常简单,只需使用distinct(columns)文档)。

Productorder.objects.all().distinct('category')

请注意,此功能自 1.4 以来已包含在 Django 中

于 2010-10-04T00:22:09.897 回答
19

用户使用该字段排序,然后进行区分。

ProductOrder.objects.order_by('category').values_list('category', flat=True).distinct()
于 2015-10-15T08:31:43.460 回答
18

其他答案很好,但这更简洁一些,因为它只给出了从 DISTINCT 查询中获得的值,而没有来自 Django 的任何内容。

>>> set(ProductOrder.objects.values_list('category', flat=True))
{u'category1', u'category2', u'category3', u'category4'}

或者

>>> list(set(ProductOrder.objects.values_list('category', flat=True)))
[u'category1', u'category2', u'category3', u'category4']

而且,它可以在没有 PostgreSQL 的情况下工作。

这比使用 .distinct() 效率低,假设数据库中的 DISTINCT 比 python 快set,但它非常适合在 shell 周围闲逛。

更新:这个答案非常适合在开发过程中在 Django shell 中进行查询。不要在生产中使用此解决方案,除非您绝对确定在应用之前始终会获得极少量的结果set。否则,从性能的角度来看,这是一个糟糕的主意。

于 2015-02-02T23:00:23.523 回答