Получение объектов queryset, сгруппированных по диапазону значений аннотации
Мне нужно отфильтровать мои объекты таким образом, чтобы они были сгруппированы по диапазону (диапазон фиксирован, для данного случая, допустим, у нас есть эти 3 диапазона [0.0, 33.0] [33.01, 66.0] [66.01, 100.0]
вот моя модель
class Item(models.Model):
name = models.CharField(
help_text="Itemname",
max_length=256
)
price = models.DecimalField(max_digits=6, decimal_places=2)
Я пытаюсь получить результат, который выглядит следующим образом
{
"0.0-33.0": [`
{
"name": "x"
}
],
"33.01-66.0": [
{
"name": "y"
},
{
"name": "Z"
}
]
}
Я пробовал что-то вроде этого:
item_by_range = Item.objects.filter(price__lte=100.0).annotate(
price_group=Case(
When(price__range=[0.0, 33.0], then=Value('0-33')),
When(price__range=[33.01, 66.0], then=Value('33-66')),
When(price__range=[66.01, 100.0], then=Value('66-100')),
default=Value('No group'),
output_field=CharField(),
)
).values('name', 'price_group').order_by('price_group')
но это работает только если я передаю в значениях только price_group, но так я теряю название товара
спасибо.
You only need to do some post-processing with groupby(…) [Python-doc] from the itertools module [Python-doc]:
from itertools import groupby
from operator import itemgetter
result = {
k: [dict(name=v['name']) for v in vs]
for k, vs in groupby(item_by_range, itemgetter('price_group'))
}
Это создаст словарь, который будет выглядеть следующим образом:
{
"0.0-33.0": [
{"name": x}
],
"33.01-66.0": [
{"name": y},
{"name": z}
}
}
Вы не можете создать объект, в котором один и тот же ключ (здесь "name") встречается несколько раз.