Я довольно озадачен лучшим способом построения запроса Django, который проверяет, присутствуют ли все элементы поля ManyToMany
(или списка) в другом поле ManyToMany
.
Например, у меня есть несколько Person
, которые могут иметь более одной специальности. Есть также Job
с, которые люди могут запустить, но им требуется один или несколько Specialty
с, чтобы иметь право на запуск.
class Person(models.Model):
name = models.CharField()
specialties = models.ManyToManyField('Specialty')
class Specialty(models.Model):
name = models.CharField()
class Job(models.Model):
required_specialties = models.ManyToManyField('Specialty')
Человек может начать работу только , если у него есть все специальности, которые требуются для работы. Итак, опять же, ради примера, у нас есть три специальности:
И у меня есть Job
, который требует специальностей «Пение и танцы». Начать его может человек, специализирующийся на пении и танцах, а другой, специализирующийся на кодировании и пении, - не может, поскольку для работы требуется человек, который может петь и танцевать.
Итак, теперь мне нужен способ найти все рабочие места, которые человек может взять на себя. Это был мой способ справиться с этим, но я уверен, что есть более элегантный подход:
def jobs_that_person_can_start(person):
# we start with all jobs
jobs = Job.objects.all()
# find all specialties that this person does not have
specialties_not_in_person = Specialty.objects.exclude(name__in=[s.name for s in person.specialties])
# and exclude jobs that require them
for s in specialties_not_in_person:
jobs = jobs.exclude(specialty=s)
# the ones left should fill the criteria
return jobs.distinct()
Это связано с тем, что при использовании Job.objects.filter(specialty__in=person.specialties.all())
будут возвращаться задания, соответствующие любым специальностям человека, но не всем. Используя этот запрос, для певческого кодера будет отображаться задание, которое требует Singing and Dancing, что не является желаемым результатом.
Я надеюсь, что этот пример не слишком запутанный. Причина, по которой я обеспокоен этим, заключается в том, что специализаций в системе, вероятно, будет намного больше, и их циклирование не кажется лучшим способом для достижения этой цели. Мне интересно, может ли кто-нибудь дать царапину этой зуд!