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

使用annotate()和values()后,Django模板循环无法渲染模型字段

问题原因

当你使用.values('venue')时,Django返回的是包含venue外键ID的字典,而非完整的Venue对象。因此模板里itemised_loyatly_card.venue只会显示ID,无法通过venue.logo访问场馆的Logo属性。

解决方案

以下两种方式都能解决问题,可根据需求选择:

方式一:在.values()中指定需要的场馆字段

修改视图代码,在.values()里通过双下划线关联外键,明确指定要获取的Venue字段,同时保留分组求和逻辑:

from django.db.models import Sum, F
def user_loyalty_card(request):
    itemised_loyalty_cards = Itemised_Loyatly_Card.objects.filter(
        user=request.user.id
    ).values(
        'venue__id', 'venue__name', 'venue__logo'
    ).annotate(
        add_points=Sum('add_points'),
        use_points=Sum('use_points')
    ).annotate(
        total=F('add_points') - F('use_points')
    )
    return render(request,"main/account/user_loyalty_card.html", {'itemised_loyalty_cards':itemised_loyalty_cards})

对应修改模板,直接通过字典键访问字段:

{% for item in itemised_loyalty_cards %}
<img src="{{ item.venue__logo }}">
{{ item.venue__name }}
{{ item.total }}
{% endfor %}

方式二:从Venue模型反向查询并注解

这种方式直接获取带求和数据的Venue对象,逻辑更直观:
修改视图代码:

from django.db.models import Sum, F
def user_loyalty_card(request):
    # 通过反向关联查询用户关联的场馆,并注解求和字段
    venues = Venue.objects.filter(
        itemised_loyatly_card__user=request.user.id
    ).annotate(
        add_points=Sum('itemised_loyatly_card__add_points'),
        use_points=Sum('itemised_loyatly_card__use_points'),
        total=F('add_points') - F('use_points')
    ).distinct()  # 去重避免同一场馆重复出现
    return render(request,"main/account/user_loyalty_card.html", {'venues': venues})

对应修改模板,直接访问Venue对象属性:

{% for venue in venues %}
<img src="{{ venue.logo }}">
{{ venue.name }}
{{ venue.total }}
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:05:40