You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何关联多对多关系的Product与Category模型列表(非QuerySet场景)

Got it, since you're dealing with a list of Product instances (not a QuerySet), Django's built-in Prefetch won't work directly here. But we can replicate that prefetch-like behavior manually by building a mapping between each Product and its associated Categories, then attaching those Categories to each Product instance. Here's how to do it efficiently:

Step 1: Extract Product IDs from your list

First, grab all the IDs of the Products in your list—this helps us fetch only the relevant Categories later (this is an in-memory operation, no database query needed):

product_ids = [product.id for product in products_list]

We'll query all Categories linked to these Products, then create a dictionary where each key is a Product ID, and the value is the list of Categories associated with that Product. Using prefetch_related ensures we avoid N+1 database queries when accessing the linked Products for each Category:

from collections import defaultdict

# Fetch all relevant Categories, prefetch their linked Products to avoid extra DB hits
categories = Category.objects.filter(products__in=product_ids).prefetch_related('products')

# Build the mapping between Product IDs and their Categories
product_categories_map = defaultdict(list)
for category in categories:
    # Iterate through Products linked to this Category
    for product in category.products.all():
        # Only add the Category to the mapping if the Product is in our original list
        if product.id in product_ids:
            product_categories_map[product.id].append(category)

Step 3: Attach Categories to each Product instance

Loop through your original products_list and assign the corresponding Categories to each Product. We'll add a custom attribute (like prefetched_categories) to each instance so you can access it just like a prefetched relation:

for product in products_list:
    # Get the Categories for this Product, default to an empty list if none exist
    product.prefetched_categories = product_categories_map.get(product.id, [])

How to use it

After setup, you can access the Categories for any Product in products_list directly without hitting the database again:

for product in products_list:
    print(f"Product: {product.name}, Categories: {[cat.name for cat in product.prefetched_categories]}")

Efficiency Notes

  • This approach only makes one database query (to fetch the relevant Categories with their linked Products).
  • Using in-memory mapping with defaultdict keeps operations fast even for larger lists of Products.

内容的提问来源于stack exchange,提问作者user3541631

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:03:45