Как получить все многие объекты в наборе объектов запроса
У меня есть модель Department
, в которой есть Role
, с которыми связаны User
. Я знаю пользователя, но мне нужно получить user.role.department_set.all()
(все отделы, к которым принадлежит роль пользователя), а затем получить все role
в каждом из этих отделов.
Модели:
class User(AbtractUser):
role = models.ForeignKey(Role)
class Role(models.Model):
name = models.CharField()
class Department(models.Model):
name = models.CharField()
roles = models.ManyToManyField()
Как я могу получить все отделы, которые содержат роль пользователя, а затем получить роли всех этих отделов?
В настоящее время я делаю нечто подобное, но это очень дорогой поиск:
def get_departments(self):
"""Returns a list of departments the user is in."""
return self.role.department_set.all()
def get_users_departments_roles(self):
"""Returns all the roles of all the departments the user is in."""
departments = self.get_departments()
roles = Role.objects.none()
for department in departments.iterator():
for role in department.roles.all():
roles |= Role.objects.filter(name=role.name)
return roles
Попутный вопрос: После того, как я все это напечатал, будет ли лучше просто добавить поле department
к каждому пользователю? Меня беспокоит то, что если роль изменится, мне придется одновременно изменить и отдел, и это добавит сложности.
Вы можете отфильтровать набор запросов Role и проследить отношения ManyToManyField в обратном направлении, используя имя department
Вы можете передать набор запросов в фильтр __in
для создания вложенного запроса
def get_users_departments_roles(self):
"""Returns all the roles of all the departments the user is in."""
departments = self.get_departments()
return Role.objects.filter(department__in=departments).distinct()
Обратите внимание, что некоторые базы данных (MySQL) не очень хорошо выполняют вложенные запросы, смотрите это предупреждение в конце этого раздела в документации