Django - Как фильтровать и возвращать данные по группам
У меня есть модель, в которой я хочу вернуть группу по атрибуту самого объекта. Предположим, что модель следующая:
class User():
username = models.CharField(max_length=50, unique=True)
group = models.CharField(max_length=20)
Позже в представлении я получу по группам всех пользователей:
group1 = User.objects.filter(group='1')
group2 = User.objects.filter(group='2')
group3 = User.objects.filter(group='3')
Но это вернет для каждой группы следующую структуру:
[{"username":"user1", "group":"1"}]
[{"username":"user2", "group":"2"}]
[{"username":"user3", "group":"3"}]
Как я могу получить следующую структуру (где группа является корнем) непосредственно из фильтра или как я могу объединить группы для достижения этого:
[
"1": [{"username":"user1","group":"1"}],
"2": [{"username":"user2","group":"2"}],
"3": [{"username":"user3","group":"3"}]
]
Я предполагаю, что у вас нет модели Group, только поле в модели User. Я не профессионал в Django, поэтому я не знаю никаких трюков Django, которые могли бы помочь вам достичь вашей цели - хотя я уверен, что Django ORM имеет некоторые функции, которые выполнят для вас запрос GROUP BY. Но почему бы вам не написать полностью питоновское решение, просто преобразовав коллекцию, которая у вас уже есть, в ту, которая вам нужна?
обновление после комментария
попробуйте что-нибудь вроде этого сценария:
from functools import reduce
users = [
{'username': 'foo', 'group':'1'},
{'username': 'bar', 'group':'2'},
{'username': 'baz', 'group':'1'},
{'username': 'asd', 'group':'2'},
{'username': 'zxc', 'group':'3'},
{'username': 'rty', 'group':'1'},
{'username': 'fgh', 'group':'2'},
{'username': 'vbn', 'group':'3'},
{'username': 'vbn', 'group':'3'},
]
def reducer(acc,el):
group = el['group']
if not acc.get(group):
acc[group]=[el.get('username')]
else:
acc[group].append(el['username'])
return acc
print(reduce(reducer, users, {}))
В результате будет выведен результат, который выглядит близко к тому, что вы хотите:
{'1': ['foo', 'baz', 'rty'],
'3': ['zxc', 'vbn', 'vbn'],
'2': ['bar', 'asd', 'fgh']}