Grouping queryset by date

依然范特西╮ 提交于 2019-12-24 08:26:03

问题


I have a class which contains a date as well as some other fields.

What I'm trying to figure out is a query which will return me each of the items, grouped by the date.

So, given the following class:-

class Item(models.Model):
    item_date = models.DateField()
    <other fields>

I'd like to get something like this:-

[
    {
        'item_date': datetime.date(2018, 9, 12),
        'items': <Queryset [<Item: item1>, <Item: item17> ...]
    }, {
        'item_date': datetime.date(2018, 9, 13),
        'items': <Queryset [<Item: item2>, <Item: item33> ...]
    }, {
        'item_date': datetime.date(2018, 9, 14),
        'items': <Queryset [<Item: item34>, <Item: item37> ...]
    } ...
]

I'm pretty sure I need some sort of annotation but I'm not 100% sure how to structure it.

The closest I've got is:-

Item.objects.values('item_date').annotate(Count('id')).order_by('item_date')

but that just gives me the counts of how many Items are on each date - not the actual Items (obviously!).

What do I need instead of that Count? Is this even possible?!


回答1:


Most (if not all) SQL databases can not return hierarchical data, or at least not without a lot of trics. You should do the ordering at the Django level, for example with itertools.groupby [Python-doc]:

from itertools import groupby
from operator import attrgetter

result = [
    {'item_date': k, 'items': list(vs)}
    for k, vs in groupby(
        Item.objects.all().order_by('item_date'),
        attrgetter('item_date')
    )
]

Typically the overhead will not be that significant, since deserializing the objects already takes linear time, and this itertools.groupby takes linear time as well.

It is important to .order_by(..) the key function, since .groupby(..) does not first look to all objects before grouping: it groups "subsequences" of elements with the same key value.



来源:https://stackoverflow.com/questions/53071211/grouping-queryset-by-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!