Python Django ORM:获取列上不同的对象,并按另一列排序
我有一个Django模型,它(极其简化)如下所示:Python Django ORM:获取列上不同的对象,并按另一列排序,python,django,django-orm,Python,Django,Django Orm,我有一个Django模型,它(极其简化)如下所示: class MyModel(models.Model): date = models.DateTimeField() number = models.PositiveIntegerField() [12, 8, 5, 14] MyModel.objects.order_by('-date').distinct('number') 我想得到一个独特的编号s的列表,按它们出现的时间倒序排列 因此,例如,对于这些数据(dates
class MyModel(models.Model):
date = models.DateTimeField()
number = models.PositiveIntegerField()
[12, 8, 5, 14]
MyModel.objects.order_by('-date').distinct('number')
我想得到一个独特的编号
s的列表,按它们出现的时间倒序排列
因此,例如,对于这些数据(date
s在此处排序以提高可读性):
我会得到一个如下的列表:
class MyModel(models.Model):
date = models.DateTimeField()
number = models.PositiveIntegerField()
[12, 8, 5, 14]
MyModel.objects.order_by('-date').distinct('number')
直觉上,我会这样写查询:
class MyModel(models.Model):
date = models.DateTimeField()
number = models.PositiveIntegerField()
[12, 8, 5, 14]
MyModel.objects.order_by('-date').distinct('number')
但这是无效的ORM代码
我如何解决这个问题
请注意,所讨论的表包含数百万行,其中可能有大量重复的
编号
s,因此我无法以“简单”的方式解决此问题(例如,迭代MyModel.objects.order_by('-date')
中的行,如果以前没有看到过,则动态拾取number
s).您可以使用SQLGROUP BY
语句来实现这一点,但说实话,我永远都不记得如何在Django的ORM中实现GROUP BY
,所以我求助于原始SQL:
number_qs = MyModel.objects.raw("""
SELECT
id, MAX(date) AS date, number
FROM
myapp_mymodel
GROUP BY
number
ORDER BY
MAX(date) DESC;
""")
numbers = [n.number for n in number_qs]
很好,但我更喜欢在代码库中避免使用原始SQL
然而,他的回答让我们更容易找到原生ORM版本,所以多亏了他!
以下是我提出的ORM版本:
results = MyModel.objects.values('number').annotate(m=Max('date')).order_by('-m')
results = [r.number for r in results]
人们似乎应该能够做到:
results = MyModel.objects.values('number').annotate(m=Max('date')).order_by('-m').values_list('number', flat=True)
但在Django 1.6中,我得到了一个
FieldError:无法将关键字'm'解析到字段中。
添加最后一个values\u list
方法时出错。也许有办法解决这个问题,但我不担心两行版本会花太多时间来解决这个问题。试试这个集合(MyModel.objects.order_by('-date')。value('number'))@Sławek这行不通;在Python中,set
是无序的。因此,不能保证数字
值的顺序正确。此外,这将导致对整个queryset进行求值,如果有数百万行,这将是一个问题。