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

如何在Django ORM中关联无正向引用的两张表?含模型查询需求

解决Django中Product与Price模型的关联查询问题

嘿,这个问题其实Django已经帮咱们考虑到啦!虽然你的Product模型里没有显式定义指向Price的字段,但Django会自动为ForeignKey字段创建反向关联关系,咱们完全可以借助它来实现关联查询。下面给你几种实用的实现方式:

1. 使用默认的反向关联名称查询

Django默认会给反向关联生成一个名称:[小写模型名]_set,这里就是price_set。咱们可以直接通过这个名称来关联查询:

# 获取所有产品及其对应的价格(优化查询避免N+1问题)
products_with_prices = Product.objects.all().prefetch_related('price_set')

# 遍历输出
for product in products_with_prices:
    print(f"产品名称: {product.name}")
    for price in product.price_set.all():
        print(f"对应价格: {price.price}")

# 如果只需要提取name和price的键值对列表,可以用values方法
result_list = Product.objects.values('name', 'price__price')
# 返回结果示例:[{'name': '手机', 'price__price': 2999}, {'name': '耳机', 'price__price': 399}]

2. 自定义反向关联名称(更直观)

如果觉得price_set这个名字不够清晰,咱们可以在Price模型的ForeignKey里添加related_name参数,自定义一个更友好的反向名称:

class Price(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='prices')
    price = models.IntegerField()

之后查询的时候就可以用自定义的prices来访问关联的价格数据了:

products_with_prices = Product.objects.all().prefetch_related('prices')
for product in products_with_prices:
    print(f"产品名称: {product.name}")
    for price in product.prices.all():
        print(f"对应价格: {price.price}")

3. 从Price表正向查询(更直接的场景)

既然Price模型已经持有Product的外键,咱们也可以换个思路,从Price出发正向关联Product来获取需要的数据,这种方式在只需要价格对应产品名称的场景下更直接:

# 提取产品名称和价格的键值对列表
result_list = Price.objects.values('product__name', 'price')

# 如果需要遍历完整的对象,用select_related优化查询(多对一关联适合用select_related)
prices_with_product = Price.objects.select_related('product').all()
for price_item in prices_with_product:
    print(f"产品名称: {price_item.product.name}, 价格: {price_item.price}")

小提示:优化查询性能

  • 当处理多对一/一对一的正向关联时,用select_related(底层是SQL JOIN,一次查询获取所有数据)。
  • 当处理一对多/多对多的反向关联时,用prefetch_related(分两次查询,Python层面关联结果)。
    这两个方法都能避免常见的N+1查询性能问题哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:10:25