Django如何高效获取多层嵌套外键关联的所有Dictionary对象
报错原因解释
Ingredient与Product为多对一关联,通过Product实例获取反向关联的Ingredient集合时,得到的是RelatedManager对象,对应多个Ingredient实例而非单个实例,因此不存在属于单个Ingredient实例的middle外键属性,这是触发AttributeError的核心原因。
注意:如果你的Ingredient模型中product外键没有设置
related_name="ingredient",反向关联的默认名称为ingredient_set,后续查询逻辑中的字段名需要对应修改。
最优实现方案
直接从Dictionary模型出发,利用Django ORM的跨关联查询语法(双下划线__)完成多层外键过滤,整个过程仅执行1次SQL查询,远优于你当前的4次查询实现:
# 已知product id的场景,无需先查询product实例 dictionaries = Dictionary.objects.filter(middle__ingredient__product_id=1) # 已经拿到product实例的场景 product = Product.objects.get(id=1) dictionaries = Dictionary.objects.filter(middle__ingredient__product=product)
实现链式调用写法
如果希望通过product实例链式调用直接获取结果,可以在Product模型中新增自定义方法封装上述查询逻辑:
class Product(models.Model): # 原有字段定义 ... def get_related_dictionaries(self): return Dictionary.objects.filter(middle__ingredient__product=self)
之后你就可以直接用以下写法获取数据:
dictionaries = product.get_related_dictionaries().all()
批量查询性能优化
如果你需要批量查询多个Product对应的关联Dictionary,可以配合prefetch_related减少查询次数:
from django.db.models import Prefetch products = Product.objects.all().prefetch_related( Prefetch( 'ingredient__middle__dictionary', queryset=Dictionary.objects.all(), to_attr='related_dictionaries' ) ) # 遍历访问时不会触发额外查询 for product in products: print(product.related_dictionaries)
内容的提问来源于stack exchange,提问作者J Zero
相关产品推荐
相关产品推荐

