在Django中selectDISTINCT个别列?
我很好奇,如果有什么办法在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
是Category
的排名。 我希望能够遍历所有类别在该类别中的每个等级上进行一些操作。
我想首先获取系统中所有类别的列表,然后查询该类别中的所有产品并重复,直到处理完每个类别。
我宁愿避免原始的SQL,但如果我必须去那里,那会很好。 尽pipe我从来没有在Django / Python中编写原始SQL。
从数据库中获取不同列名的列表的一种方法是使用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"
这里有几件事要记住。 首先,这将返回一个与QuerySet
行为不同的ValuesQuerySet
。 当你访问的时候,第一个元素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()
实际上, 如果您使用的是PostgreSQL ,那么使用distinct(columns)
就非常简单了。
Productorder.objects.all().distinct('category')
请注意,自1.4版本以来,这个特性已经包含在Django中
其他答案是好的,但是这是一个更清洁,因为它只给出像从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中进行讨厌是非常好的。
用户通过该字段进行sorting,然后执行截然不同的操作。
ProductOrder.objects.order_by('category').values_list('category', flat=True).distinct()