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

如何在Django中通过关联关系输出对象?现有模板写法是否可行?

Django模板中关联对象遍历写法问题

我不太清楚如何用数据库术语准确描述该需求,我希望输出与另一个对象存在关联关系的对象,例如通过order__orderitem.product.title这样的形式获取商品标题。

以下是我的代码:

models.py

class Order(models.Model):
    status_types = [
        ("Ordered", "Ordered"),
        ("Sent", "Sent"),
        ("Delivered", "Delivered"),
        ("Extended", "Extended"),
        ("Returned", "Returned"),
    ]
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    order_date = models.DateTimeField()
    return_date = models.DateTimeField(null=True)
    status = models.CharField(choices=status_types, default="Ordered", max_length=100)
    total = models.IntegerField(null=False)
    payment = models.OneToOneField(Payment, on_delete=models.CASCADE, null=False, blank=False)
    shipping = models.ForeignKey(Shipping, on_delete=models.CASCADE, null=False, blank=False)
    first_name = models.CharField(max_length=255, null=False, blank=False)
    last_name = models.CharField(max_length=255, null=False, blank=False)
    phone = models.CharField(max_length=12, null=False, blank=False)
    city = models.CharField(max_length=255, null=False, blank=False, default=None)
    zip_code = models.CharField(max_length=10, null=False, blank=False, default=None)
    street = models.CharField(max_length=255, null=False, blank=False, default=None)
    building_number = models.CharField(max_length=10, null=False, blank=False, default=None)
    apartment_number = models.CharField(max_length=10, null=True, blank=True, default=None)


class OrderItem(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    price = models.IntegerField(null=False, blank=False, default=15)
    debt = models.IntegerField(null=True, default=0)

orders.html

{% for item in object_list %}
    {% for it in item__OrderItem %}
                    {{ it.product.title }}
    {% endfor %}
{% endfor %}

请问这种写法是否可行?


回答

你模板里的item__OrderItem写法完全不可行,Django模板中访问关联对象要遵循以下规则:

  1. 默认反向关联管理器:因为OrderItem通过外键order关联到Order,Django会自动为Order模型生成一个反向关联查询管理器,默认名称是orderitem_set(小写模型名 + _set)。所以正确的遍历写法应该是:
{% for item in object_list %}
    {% for it in item.orderitem_set.all %}
        {{ it.product.title }}
    {% endfor %}
{% endfor %}
  1. 自定义关联名称(更推荐):如果觉得默认的orderitem_set不够直观,可以在OrderItem的外键字段里设置related_name参数,修改模型代码:
class OrderItem(models.Model):
    # ... 其他字段
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='order_items')
    # ... 其他字段

之后模板里就可以用更清晰的名称遍历:

{% for item in object_list %}
    {% for it in item.order_items.all %}
        {{ it.product.title }}
    {% endfor %}
{% endfor %}
  1. 性能优化建议:如果订单数量较多,建议在视图中使用prefetch_related预取关联的OrderItem数据,避免N+1查询问题,比如在视图里写:
orders = Order.objects.all().prefetch_related('order_items')  # 对应自定义的related_name
# 或者用默认名称
orders = Order.objects.all().prefetch_related('orderitem_set')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:15:02