使用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
相关产品推荐
相关产品推荐

