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

Django如何在HTML模板中获取关联模型的最新价格记录

实现方案

你写的{{ product.id.price }}逻辑不成立:product.id是产品主键的整数值,没有关联价格的属性,自然取不到值。正确实现优先在视图层完成数据预处理,避免模板层查询导致的N+1性能问题,步骤如下:

1. 修正视图层逻辑,预取最新价格

原代码有两个基础问题:一是模型名笔误,定义的模型是Product不是Products;二是没有提前关联价格数据,直接在模板查会产生大量重复数据库请求。
修改views.py,使用Django内置的Prefetch对象提前把每个产品的最新价格绑定到产品实例上:

from django.db.models import Prefetch
from .models import Product, PriceHistory

@login_required
def overview(request):
    # 定义价格历史的预取规则:按创建时间倒序,第一条就是最新价格
    latest_price_prefetch = Prefetch(
        lookup='pricehistory_set', # 外键默认反向关联名
        queryset=PriceHistory.objects.order_by('-creation_date'),
        to_attr='latest_price_list' # 把预取结果存在这个自定义属性上
    )
    all_products = Product.objects.filter(
        user=request.user
    ).prefetch_related(latest_price_prefetch)
    
    general_context = {'all_products': all_products}
    return render(request, 'overview.html', general_context)

说明:因为PriceHistory关联Product的外键字段没有指定related_name,Django默认生成的反向关联名为小写模型名_set,也就是pricehistory_set。


2. 修正模板代码,渲染价格

原模板存在标签闭合错误:<tr>写在循环内,</tr>却写在循环外,会导致表格结构错乱。修正后直接读取预取的最新价格即可:

<h4>Overview Products</h4>
<table>
  <thead>
    <tr>
      <th>#</th>
      <th>Name</th>
      <th>Url</th>
      <th>Last price</th>
    </tr>
  </thead>
  <tbody>
    {% for product in all_products %}   
    <tr>                    
      <td>{{ forloop.counter }}</td>
      <td>{{ product.name|default:"未命名产品" }}</td>
      <td>{{ product.url|default:"未录入链接" }}</td>
      <td>
        {% with latest=product.latest_price_list.0 %}
          {{ latest.price|default:"暂无价格记录" }}
        {% endwith %}
      </td>
    </tr>
    {% endfor %}
  </tbody>
</table>

这里用with标签取预取列表的第一个元素(也就是创建时间最新的价格记录),同时加了默认值处理,避免没有价格数据时页面显示空白或者报错。

可选优化

如果觉得默认反向关联名不好记,可以给外键加related_name参数,修改models.py中的PriceHistory外键字段:

product_info  = models.ForeignKey(
    Product, 
    on_delete=models.CASCADE,
    related_name='price_records' # 自定义反向关联名
)

修改后执行数据库迁移命令python manage.py makemigrations、python manage.py migrate,之后视图里Prefetch的lookup参数替换为'price_records'即可,代码语义更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:54:16