I need to filter my objects in a way to get them grouped by range (range is fixed, for this case let’s say we have these 3 ranges [0.0, 33.0] [33.01, 66.0] [66.01, 100.0]
here is my model
class Item(models.Model):
name = models.CharField(
help_text="Itemname",
max_length=256
)
price = models.DecimalField(max_digits=6, decimal_places=2)
I am trying to get a result that looks like this
{
"0.0-33.0": [`
{
"name": "x"
}
],
"33.01-66.0": [
{
"name": "y"
},
{
"name": "Z"
}
]
}
I tried something like this:
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')
but this only works if I pass only price_group in values but this way I lose the name of the item
thanks.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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 <strong>groupby(</strong>item_by_range, itemgetter('price_group')<strong>)</strong>
}
This will make a dictionary that looks like:
{
"0.0-33.0": [
{"name": x}
],
"33.01-66.0": [
{"name": y},
{"name": z}
}
}
You can not make an object where the same key (here "name") occurs multiple times.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0