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

2024-03-07

我的数据库具有以下架构:

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)

换句话说,一个Product有很多Tags 和一个Product有很多AlternatePartNumbers. Tags 是属性的集合Product.

给定 a 中的三个属性Tag,我要选择关联的Product匹配的(可能不止一个),以及所有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 %}

这可以运行数千个查询,具体取决于匹配的数量。有没有好的方法来优化这个?我尝试使用Tag.objects.select_related().filter...这对一些人有所帮助,但还不够。


Product 和AlternatePartNumber 之间的关系是反向ForeignKey 关系,因此select_related()行不通的。你需要prefetch_related(),这比select_related()但可以处理多对一的关系。

我自己以前没有使用过 prefetch_lated() 但如果我正在阅读文档 https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related正确地,你需要类似的东西Tag.objects.prefetch_related('product__alternatepartnumber_set').filter...。如果这不起作用,请在 AlternatePartNumber 模型上指定 related_name 并使用它来代替alternatepartnumber_set.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐