Django ORM запрос
Нужна помощь составить запрос, у меня есть модель:
class Member(models.Model):
customer = models.CharField(max_length=50)
item = ArrayField(models.CharField(max_length=50))
total = models.IntegerField()
Нужно сделать запрос для вывода только первых пяти customer по полю total (это я знаю, как сделать), но далее в поле item каждого customer нужно вывести только те камни, которые встречаются не менее двух раз у других customer этого топ пять.
Как правильно реализовать этот запрос?
Ответы (1 шт):
Автор решения: Jack_oS
→ Ссылка
Можно выбрать топ-5 members по total:
members_qry = Member.objects.order_by('-total')[:5]
и записать в словарь:
members = [{'customer': m.customer, 'stones': m.item, 'total': m.total} for m in members_qry]
Допустим, members выглядит так:
>>> members
[
{'customer': 'joe', 'total': 13, 'stones': ['бриллиант', 'сапфир', 'аметист']},
{'customer': 'dou', 'total': 12, 'stones': ['изумруд', 'сапфир', 'малахит']},
{'customer': 'foo', 'total': 12, 'stones': ['топаз', 'берилл', 'оникс', 'аметист', 'изумруд']},
{'customer': 'bar', 'total': 9, 'stones': ['изумруд', 'сапфир', 'малахит']},
{'customer': 'spam', 'total': 9, 'stones': ['топаз', 'аметист', 'сапфир', 'берилл']}
]
Тогда количество камней у всех будет:
stones_dict = dict()
for m in members:
for s in m['stones']:
stones_dict[s] = stones_dict.get(s, 0) + 1
в stones_dict:
>>> stones_dict
{'бриллиант': 1, 'сапфир': 4, 'аметист': 3, 'изумруд': 3, 'малахит': 2, 'топаз': 2, 'берилл': 2, 'оникс': 1}
И потом удалить те камни, которые встречаются у двух и меньше members:
for m in members:
for s in m['stones'].copy():
if stones_dict[s] < 3:
m['stones'].remove(s)
В итоге в members:
>>> members
[
{'customer': 'joe', 'total': 13, 'stones': ['сапфир', 'аметист']},
{'customer': 'dou', 'total': 12, 'stones': ['изумруд', 'сапфир']},
{'customer': 'foo', 'total': 12, 'stones': ['аметист', 'изумруд']},
{'customer': 'bar', 'total': 9, 'stones': ['изумруд', 'сапфир']},
{'customer': 'spam', 'total': 9, 'stones': ['аметист', 'сапфир']}
]