我现在已经搜索了很长一段时间并且知道了几个问题的答案,但即使我的问题非常简单,也没有一个解决方案在我的最后工作:
我需要什么(使用postgres + django 1.10):我有很多行,在datetime字段中有许多重复日期(=天)。我想要一个包含每个日期/日的一行/对象的查询集。
fk | col1 | colX | created (type: datetime)
----------------------------------------------
1 | info | info | 2016-09-03 08:25:52.142617+00:00 <- get it (time does not matter)
1 | info | info | 2016-09-03 16:26:52.142617+00:00
2 | info | info | 2016-09-03 11:25:52.142617+00:00
1 | info | info | 2016-09-14 16:26:52.142617+00:00 <- get it (time does not matter)
3 | info | info | 2016-09-14 11:25:52.142617+00:00
1 | info | info | 2016-09-25 23:25:52.142617+00:00 <- get it (time does not matter)
1 | info | info | 2016-09-25 16:26:52.142617+00:00
1 | info | info | 2016-09-25 11:25:52.142617+00:00
2 | info | info | 2016-09-25 14:27:52.142617+00:00
2 | info | info | 2016-09-25 16:26:52.142617+00:00
3 | info | info | 2016-09-25 11:25:52.142617+00:00
etc.
这是最好的(性能+ pythionic / django)方式。我的模型/表格将有很多行(>百万)。
编辑1
必须先用fk(例如WHERE fk = 1)过滤结果。
我已经尝试过最明显的事情,比如
MyModel.objects.filter(fk=1).order_by('created__date').distinct('created__date')
但出现以下错误:
django.core.exceptions.FieldError:无法解析关键字&#39; date&#39;进入田野。加入&#39;创建&#39;不允许。
...与all()的相同错误以及通过类Meta而不是query-method order_by()的相应排序......
在这种特定情况下,有人可能会更多地了解这个错误吗?
答案 0 :(得分:1)
在当前的Django实现中似乎不可能,因为这将涉及使用高级DB后端函数(如Postgres window functions)。
你最接近的是使用聚合:
MyModel.objects.annotate(
created_date=TruncDay('created')
).values('created_date').annotate(id=Min('id'))
这将聚合相似的日期,并获取最小ID。
[{'created_date': datetime.date(2017, 3, 16), 'id': 146},
{'created_date': datetime.date(2017, 3, 28), 'id': 188},
{'created_date': datetime.date(2017, 3, 24), 'id': 178},
{'created_date': datetime.date(2017, 3, 23), 'id': 171},
{'created_date': datetime.date(2017, 3, 22), 'id': 157}] ...
如果您需要整个对象,可以使用.values_list()
和另一个查询集进行链接,这将产生一个子查询:
MyModel.objects.filter(
id__in=MyModel.objects.annotate(
created_date=TruncDay('created')
).values('created_date').annotate(id=Min('id')).values_list(
'id', flat=True
)
)
仅供参考,这导致以下查询
SELECT
"myapp_mymodel"."id",
"myapp_mymodel"."created",
"myapp_mymodel"."col1",
"myapp_mymodel"."colX"
FROM "myapp_mymodel"
WHERE "myapp_mymodel"."id" IN (
SELECT MIN(U0."id") AS "id"
FROM "myapp_mymodel" U0
GROUP BY DATE(U0."created")
)
答案 1 :(得分:-2)
您可以使用Queryset通过创建值的不同来获取表中的结果,因为您使用的是postgresql。
也许像这样的查询应该做的工作:
MyModel.objects.all().distinct('created__date')
我也引用了django的查询集文档:https://docs.djangoproject.com/fr/1.10/ref/models/querysets/#distinct