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

Django嵌套For循环问题:父循环与子循环Model.id不匹配

问题核心原因

视图层遍历场馆时,每次循环都执行了reward_positions = [],直接重置了这个列表,导致最终传入模板的reward_positions只保留了最后一个场馆的奖励程序数据,模板自然无法匹配当前循环的场馆ID。

修复方案

1. 重构视图层数据存储逻辑

将reward_positions从列表改为字典,用场馆ID作为键,存储对应场馆的所有奖励位置数据:

def list_venues(request):
    venue_markers = Venue.objects.filter(venue_active=True)
    
    bar_total_lenght = 100
    rewards_available_per_venue = 0
    reward_position_on_bar = 0
    venue_data = {}
    # 初始化字典,而非列表
    reward_positions = {}
    
    for venue in venue_markers:
        print(f'venue name ={venue}')
                
        venue.reward_programs = venue.venuerewardprogram.all()
        reward_program_per_venue = venue.reward_programs
        
        # 用列表推导式简化数据收集
        reward_points_per_venue_test = [rp.points for rp in reward_program_per_venue]
        reward_points_per_venue_test.sort(reverse=True)
        
        highest_reward = reward_points_per_venue_test[0] if reward_points_per_venue_test else 0

        if reward_program_per_venue:
            rewards_available_per_venue = reward_program_per_venue.count()
                    
            if rewards_available_per_venue > 0:
                # 为当前场馆创建专属的奖励位置列表
                current_venue_rewards = []
                for rewardprogram in reward_program_per_venue:
                    reward_points = rewardprogram.points
                    # 避免除以0的异常
                    if highest_reward == 0:
                        reward_position_on_bar = 0
                    else:
                        reward_position_on_bar = reward_points / highest_reward
                    current_venue_rewards.append((venue, reward_points, reward_position_on_bar))
                # 将当前场馆数据存入字典,键为场馆ID
                reward_positions[venue.id] = current_venue_rewards
                print(f'Reward positions for {venue.id} = {current_venue_rewards}')

    context = {'reward_positions':reward_positions,'venue_data':venue_data,'venue_markers':venue_markers}
    
    return render(request,'template.html',context)

2. 修改模板层匹配逻辑

根据当前循环的venue.id,直接从字典中取出对应场馆的奖励数据:

{% load custom_filters %} <!-- 先加载自定义过滤器 -->
{%for venue in venue_markers%}
    {%for key, value in venue_data.items%}
        {%if key == venue.id%}
            {% with venue_rewards=reward_positions|get_item:venue.id %}
                {% for reward_position in venue_rewards %}
                    {{reward_position.0.id}} <!-- 现在会匹配当前场馆ID -->
                    {{key}}
                {% endfor %}
                <div class="progress-bar bg-success" role="progressbar" style="width: {{value}}%" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="100"></div>
            {% endwith %}
        {%endif%}
    {%endfor%}
{%endfor%}

注:Django模板默认没有字典取值的过滤器,需自定义:
在app的templatetags目录下创建custom_filters.py:

from django import template

register = template.Library()

@register.filter(name='get_item')
def get_item(dictionary, key):
    return dictionary.get(key)

额外优化点

  • 用列表推导式简化奖励点数收集,提升代码可读性
  • 增加除以0的异常处理,避免无奖励数据时报错
  • 移除冗余的pass语句,精简代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:15:02