【发布时间】:2010-12-22 22:50:56
【问题描述】:
我对构建 Django 查询的最佳方式感到困惑,该查询检查 所有 ManyToMany 字段(或列表)的元素是否存在于另一个 ManyToMany 字段中。
例如,我有几个Persons,他们可以拥有多个专长。也有Jobs 可供人们启动,但他们需要一个或多个Specialtys 才有资格启动。
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()) 将返回与该人的任何专长相匹配的工作,而不是所有专长。使用这个查询,需要唱歌和跳舞的工作会出现给唱歌的编码员,这不是想要的输出。
我希望这个例子不会太复杂。我担心这一点的原因是系统中的专长可能会更多,而循环遍历它们似乎不是实现这一目标的最佳方法。我想知道是否有人可以从头开始治疗这种痒!
【问题讨论】:
标签: django django-queryset django-orm