Присоединяйтесь и получайте кверисет в соответствии с полем многие ко многим
У меня есть модель MyUser с ForeignKey и ManyToMany связанными полями city и skills:
class MyUser(AbstractBaseUser):
email = models.EmailField()
skills = models.ManyToManyField('jobs.Skill')
class Skill(models.Model):
name = models.CharField()
предположим, что это данные моей таблицы в базе данных
{'email': 'some@email.com', 'skills': ['Python', 'Java']},
{'email': 'another@email.com', 'skills': ['JavaScript', 'C#', 'Python']}
>>> MyUser.objects.all().count()
выход равен 2, но я хочу
MyUser.objects. ..........
ответьте на 5 моих вопросов, используя следующие данные
{'email': 'some@email.com', 'city': 'London', 'skills': 'Python'},
{'email': 'some@email.com', 'city': 'London', 'skills': 'Java'},
{'email': 'another@email.com', 'city': 'Berlin', 'skills': 'JavaScript'},
{'email': 'another@email.com', 'city': 'Berlin', 'skills': 'C#'},
{'email': 'another@email.com', 'city': 'Berlin', 'skills': 'Python'},
Вы можете использовать annoate()
, с агрегацией Count и values()
для получения желаемого результата так:
from django.db.models import Count
all_users = MyUser.objects.annotate(num_skills=Count('skills')).values('email', 'num_skills')
data = []
for single_user in all_users:
email = single_user['email']
num_skills = single_user['num_skills']
skills = MyUser.objects.get(email=email).skills.all()
for skill in skills:
data.append({'email': email, 'city': 'London', 'skills': skill.name})
print(data)
Очевидно, что это не лучшее решение, так как значение city
жестко закодировано в London
и Berlin
для первого и второго пользователя соответственно.
Вы можете просто запросить следующим образом:
MyUser.objects.values('email', 'city', 'skills__name')
Вы также можете переименовать поле skills__name
следующим образом:
MyUser.objects.annotate(skill=F('skills__name')).values('email', 'city', 'skill')