Django中的奇数values_list和过滤器行为

时间:2013-06-16 14:56:54

标签: python django django-models

我正在尝试减少Django应用程序中数据库的查询数量。我不想使用三个嵌套循环来执行大量数据库查询,而是使用我所描述的the method

给定两个班级Parentorg

class Parentorgs(models.Model):
  parentorg = models.IntegerField(primary_key=True, db_column = 'parentorg_id', unique = True)
  parentorgname = models.CharField(max_length=100L, db_column='ParentOrg', unique = True) # Field name made lowercase.
  eff_date = models.DateField()
  exp_date = models.DateField(null=True, blank=True)

Contracts

class Contracts(models.Model):
  parentorg = models.ForeignKey("Parentorgs")
  contractnum = models.CharField(max_length=10L, db_column='ContractNum', primary_key = True) 
  eff_date = models.DateField()
  exp_date = models.DateField(null=True, blank=True)
  contractname = models.CharField(max_length=100L, db_column='ContractName')

我希望基于主外键关系将结果与表之间的SQL内连接相同。目前,我正在这样做

for d in Parentorgs.objects.all():
  for e in Contracts.objects.filter(parentorg_id = e.parentorg) :

正如您所看到的,这非常低效,并且会对数据库造成相当大的负担。

作为替代方案,我试过

parentorg = Parentorgs.objects.values_list("pk", flat = True)
contracts = Contracts.objects.filter(parentorg_id = parentorg).values_list("pk", flat = True)

这从Parentorgs获取预期的主键,但contracts是一个空列表。

如果我将filter(parentorg_id = parentorg).values_list("pk", flat = True)替换为all,我会从Contracts获得700多个结果,这是预期的结果。

1 个答案:

答案 0 :(得分:2)

不应该是:

parentorg = Parentorgs.objects.values_list("pk", flat=True)
contracts = Contracts.objects.filter(parentorg_id__in=parentorg)

您需要使用__in

虽然说实话,这会给你带来与

相同的结果
Contracts.objects.all()

(看作parentorg不能为空......)