如何在没有使用Django ORM的数百个查询的情况下选择多对一到多个?

dav*_*gan 1 python django query-optimization django-models django-orm

我的数据库有以下架构:

class Product(models.Model):
    pass

class Tag(models.Model):
    product = models.ForeignKey(Product)
    attr1 = models.CharField()
    attr2 = models.CharField()
    attr3 = models.CharField()

class AlternatePartNumber(models.Model):
    product = models.ForeignKey(Product)
Run Code Online (Sandbox Code Playgroud)

换句话说,a Product有很多Tags,而a Product有很多AlternatePartNumbers. Tags是一组属性的集合Product.

给定a中的三个属性Tag,我想选择Product匹配的s(可能多于一个),以及AlternatePartNumber每个产品的所有s.

目前我这样做:

# views.py
results = Tag.objects.
    filter(attr1=attr1).
    filter(attr2=attr2).
    filter(attr3=attr3)

# a template
{% for result in results %}
    {% for alternate in result.product.alternatepartnumber_set.all %}
        {{ alternate.property }}
    {% endfor %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

这可以运行数千个查询,具体取决于匹配的数量.有没有一种优化方法?我试过使用Tag.objects.select_related().filter...,这有些帮助,但它没有帮助.

And*_*ter 6

Product和AlternatePartNumber之间的关系是反向ForeignKey关系,因此select_related()不起作用.你需要的是prefetch_related(),这种攻击性能比select_related()一对一的关系要小,但可以处理多对一的关系.

我之前没有使用过prefetch_related()但是如果我正确地阅读文档,你需要类似的东西Tag.objects.prefetch_related('product__alternatepartnumber_set').filter....如果这不起作用,请在AlternatePartNumber模型上指定related_name,而不是使用它alternatepartnumber_set.