Django复杂查询而不使用循环

时间:2011-07-08 17:10:38

标签: django django-models

我有两个模型

class Employer(models.Model):
    name = models.CharField(max_length=1000,null=False,blank=False)
    eminence = models.IntegerField(null=False,default=4)

class JobTitle(models.Model):
    name = models.CharField(max_length=1000,null=False,blank=False)
    employer= models.ForeignKey(JobTitle,unique=False,null=False)

class People(models.Model):
    name = models.CharField(max_length=1000,null=False,blank=False)
    jobtitle = models.ForeignKey(JobTitle,unique=False,null=False)

我想列出每个雇主的5个雇主和一个职位。但是,工作头衔应该从雇主人数最多的前10个职位上获取。

一种方法可能是

employers = Employer.objects.filter(isActive=True).filter(eminence__lt=4 ).order_by('?')[:5]

for emp in employers:
    jobtitle = JobTitle.objects.filter(employer=emp)... and so on.

然而,通过选定的雇主循环可能是无效的。有没有办法在一个查询中执行此操作?

由于

2 个答案:

答案 0 :(得分:0)

有!查看:https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related

select_related()告诉Django使用JOIN跟踪所有外键关系。这将导致一个大型查询,而不是许多小查询,在大多数情况下,这是您想要的。您获得的QuerySet将被预先填充,Django将不必从数据库中延迟加载任何内容。

我过去曾使用select_related()来解决这个问题。

答案 1 :(得分:0)

我已经编写了这样的代码块,但它确实有用。虽然我循环employers因为我使用了select_related('jobtitle'),但我认为它没有命中数据库并且运行得更快。

employers = random.sample(Employer.objects.select_related('jobtitle').filter(eminence__lt=4,status=EmployerStatus.ACTIVE).annotate(jtt_count=Count('jobtitle')).filter(jtt_count__gt=0),3)

jtList = []
for emp in employers:
    jt = random.choice(emp.jobtitle_set.filter(isActive=True).annotate(people_count=Count('people')).filter(people_count__gt=0)[:10])
    jtList.append(jt)