Django模板中如何通过JS/AJAX条件使用render传入的数据库数据
Django模板条件渲染后端数据实现方案
你可以根据业务数据量选择以下两种实现方式:
方案一:前端预渲染隐藏(轻量场景首选)
适合buttoning数据量不大的场景,无需额外开发接口,实现成本最低。
首先修正原模板的错误:循环生成的元素不能使用重复id,将id="menu"改为class="menu",提前渲染buttoning列表并默认隐藏,再通过JS控制显隐:
<!-- 修正后的西装列表 --> <ul id="suit-list"> {% for element in suit_prods %} <li> <a href="javascript:;"> <div class="menu"> <img src="{{ element.img.url }}" alt="{{ element.title }}"> <span class="suit-title">{{ element.title }}</span> <span></span> </div> </a> </li> {% endfor %} </ul> <!-- 预渲染纽扣列表,默认隐藏 --> <ul id="buttoning-list" style="display: none;"> {% for element in buttoning %} <li> <a href="#"> <div class="buttoning-item"> <img src="{{ element.img.url }}" alt="{{ element.title }}"> <span>{{ element.title }}</span> <span></span> </div> </a> </li> {% endfor %} </ul> <script> document.querySelectorAll('.menu').forEach(menuItem => { menuItem.addEventListener('click', function() { const currentTitle = this.querySelector('.suit-title').textContent.trim(); const buttoningList = document.getElementById('buttoning-list'); // 匹配到指定西装标题则展示纽扣列表,否则可按需隐藏或不处理 buttoningList.style.display = currentTitle === 'two_piece_suit' ? 'block' : 'none'; }) }) </script>
方案二:AJAX动态请求(大数据/动态更新场景首选)
适合buttoning数据量较大、或者数据需要实时更新的场景,避免页面初始加载冗余数据。
步骤1:新增后端接口
修改views.py,新增返回纽扣数据的JSON接口:
from django.shortcuts import render from django.http import JsonResponse def index(request): suit_prods = Suit.objects.all() context = { "suit_prods": suit_prods } return render(request, "index/index.html", context) # 新增纽扣数据接口 def get_buttoning(request): # 格式化返回字段,拼接完整图片路径 buttoning_data = list(Buttoning.objects.values('title', 'img')) for item in buttoning_data: item['img'] = request.build_absolute_uri(item['img']) return JsonResponse({"code": 200, "data": buttoning_data})
步骤2:新增接口路由
在对应app的urls.py中新增路由:
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('api/get-buttoning/', views.get_buttoning, name='get_buttoning'), ]
步骤3:模板编写请求逻辑
<!-- 修正后的西装列表 --> <ul id="suit-list"> {% for element in suit_prods %} <li> <a href="javascript:;"> <div class="menu"> <img src="{{ element.img.url }}" alt="{{ element.title }}"> <span class="suit-title">{{ element.title }}</span> <span></span> </div> </a> </li> {% endfor %} </ul> <script> document.querySelectorAll('.menu').forEach(menuItem => { menuItem.addEventListener('click', async function() { const currentTitle = this.querySelector('.suit-title').textContent.trim(); // 非目标标题直接返回 if (currentTitle !== 'two_piece_suit') { const existingList = document.getElementById('buttoning-list'); if (existingList) existingList.style.display = 'none'; return; } // 已渲染过直接展示,避免重复请求 const existingList = document.getElementById('buttoning-list'); if (existingList) { existingList.style.display = 'block'; return; } // 发起请求获取数据并渲染 try { const res = await fetch('/api/get-buttoning/'); const result = await res.json(); if (result.code !== 200) return; const buttoningList = document.createElement('ul'); buttoningList.id = 'buttoning-list'; result.data.forEach(item => { const li = document.createElement('li'); li.innerHTML = ` <a href="#"> <div class="buttoning-item"> <img src="${item.img}" alt="${item.title}"> <span>${item.title}</span> <span></span> </div> </a> `; buttoningList.appendChild(li); }) // 插入到西装列表后,可按需调整插入位置 document.getElementById('suit-list').after(buttoningList); } catch (e) { console.error('纽扣数据加载失败:', e); } }) }) </script>
注意事项
- 模板中循环生成的DOM元素禁止使用重复id,必须替换为class属性,否则会导致DOM选择异常
- 如果接口使用POST请求,需要携带Django CSRF Token,避免校验失败
- 生产环境可给接口添加权限校验、参数校验,避免数据泄露
内容的提问来源于stack exchange,提问作者Neha AK
相关产品推荐
相关产品推荐

