我正在尝试做这样的事情:

class A(models.Model):
    members = models.ManyToManyField(B)

class B(models.Model):
    pass

# not sure what the right query is here
results = A.objects.all().[members.extra(select={"extra_field": ...})?]

# I want to be able to write this using the result of my query:
for r in result:
    for m in r.members:
        print m.extra_field

是否可以填充这个extra_field而无需为成员中的每个模型B创建新查询?

===============>>#1 票数:2 已采纳

在Django 1.4中预取到手之前,这会有些麻烦。 抓住你的帽子。

首先,您需要能够查询链接两个模型的表。 如果您不想显式定义通过表,则可以使用非托管模型,如下所示:

class AB(models.Model):
    a = models.ForeignKey('A')
    b = models.ForeignKey('B')

    class Meta:
        db_table = 'myapp_a_b'
        managed = False

有了这个之后,您可以深呼吸,hold住鼻子,然后执行以下操作:

# Grab the links between A and B
a_b_relationships = AB.objects.all().values('a_id', 'b_id')

# Make an indexed reference for your B objects
all_b = B.objects.all().extra(select={'extra_field': ...})
b_dict = dict((b.pk, b) for b in all_b)

# Make a dict so that for any given A object we can immediately grab
# a list of its B objects
b_by_a = {}
for rel in a_b_relationships:
    a_id = rel['a_id']
    b = b_dict[rel['b_id']]

    if a_id not in b_by_a:
        b_by_a[a_id] = []

    if b not in b_by_a[a_id]
        b_by_a[a_id].append(b)

results = A.objects.all()

for r in result:
    members = b_by_a.get(r.id, [])

    for m in members:
        print m.extra_field

这很讨厌,但它确实有效。 请记住,如果A和B表开始变大,那么您将遇到性能问题 - Django对象占用大量内存并且迭代速度非常慢。 如果您最终过滤或分块A,您还必须将相应的过滤器添加到AB和B查询中。

如果有人有更清洁/更有效的方法,我很想知道!

===============>>#2 票数:1

这个有可能,

https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related

===============>>#3 票数:0

现在我们在Django 1.6,这是微不足道的:

results = B.objects.prefetch_related('a')

  ask by int3 translate from so

未解决问题?本站智能推荐: