选择多个对象多对多

时间:2011-10-30 19:57:17

标签: django django-models django-orm

有以下型号:

class Schema(models.Model):
    keys = models.ManyToManyField(Key, through='SchemaHasKey')
    # ...

class Key(models.Model):
    name   = models.CharField(max_length=50)
    # ...

我需要用键选择10个第一个模式,但我的方式很糟糕:

schemas = []

for schema in Schema.objects.all().order_by('pk')[:10]:
    schema.key = schema.keys.all()
    schemas.append(schema)

.select_related()效果不佳:

schemas = Schema.objects.select_related().order_by('pk')[:10]

这可以在一定数量的SQL查询中完成吗?

2 个答案:

答案 0 :(得分:2)

prefetch_related功能正式启动之前,我可以这样做。

2个查询。

from collections import defaultdict

schemas = Schema.objects.order_by('pk')[:10]
key_map = defaultdict(lambda:[]) # always return a list

# use m2m through table to get all schema-key relationships related to the 10
# create a list of each `Key` with the Schema ID as the dict key.
[key_map[through.schema.id].append(through.key) for 
    through in Schema.keys.through.objects.filter(schema__in=schemas)]

for schema in schemas:
    schema.keys = key_map[schema.id]

答案 1 :(得分:1)

编辑: prefetch_related仅适用于Django开发版。

我认为您可以使用djangos prefetch_related功能。它还支持ManyToMany字段。它不会在一个SQL查询中进行连接,但可能会以不同的方式加速它。

可以像这样使用:

Schema.objects.all().prefetch_related('keys').order_by('pk')[:10]