在Django中有效查找多个模型外键集

时间:2011-05-05 23:21:36

标签: django django-models django-queryset

我有两种模式:

from django.db import Models
LANGUAGES = (
  ('en','English'),
  ('es','Spanish'),
)
class Group(models.Model):
  key = models.CharField(max_length=200)

class Data(models.Model):
  group = models.ForeignKey('Group')
  lang = models.CharField(max_length=2,choices=LANGUAGES)
  ...

我打算生成一个xml文件:

<?xml version="1.0"?>
<groups>
  <group key="key1">
    <data lang="en">Some Data</data>
    <data lang="es">Some Data</data>
  </group>
  ...
</groups>

xml文件将包含表中的所有Group和Data条目。我想避免遍历每个组g,并调用g.data_set.all(),这是与组表中的行相关的O(n)数据库连接。

我的第一个想法是创建一个字典:{'key':[data1,data2,...],...}

data = Data.objects.select_related('group').all()
groups = {}
for d in data.iterator():
  key = d.group.key
  if key in groups:
    groups[key].append(d)
  else:
    groups[key] = [d]

这对于这种情况会很好用,但如果我想在Group中添加另一个字段,事情就会变得复杂起来。对于更复杂的数据集的查找,这种方法可能不起作用。理想情况下,我可以在类似于Group.data_set的查询中进行Django查找Group.objects.all(),然后正常访问它 - group.data_set.all() - 而不会导致其他数据库命中。

1 个答案:

答案 0 :(得分:0)

如果你想尽可能地减少数据库的使用,你可以把所有内容都拉出来,然后用python创建一个结果字典。这可能是内存使用的一大缺点。

data = list(Data.objects.all().values()) # create a list of all list
groups = [(x.key, x.id) for x in Group.objects.all()] # get a list of group key & id's
results = {}
for key, id in groups:
    results[key] = [x for x in data if x['group_id'] == id]

在Django 1.3中,您可以在交互式shell中获得非常好的日志记录信息:

>>> import logging
>>> l = logging.getLogger('django.db.backends')
>>> l.setLevel(logging.DEBUG)
>>> l.addHandler(logging.StreamHandler())

现在,当您尝试不同的查询时:

>>> groups = Group.objects.all() 

>>> list(groups) # Querysets are lazy!
(0.000) SELECT "groups_group"."id", "groups_group"."key" FROM "groups_group"; args=()
<<< 
[<Group: Group object>,
 <Group: Group object>]

非常有用!