如何用JavaScript在Django模板中动态联动填充下拉选择列表?
实现制造商联动筛选类型的方案
看起来你已经搭好了基础的过滤界面,要实现选择Manufacturer后Type下拉列表只显示对应选项,我们可以通过Django后端提供数据接口,配合简单的JavaScript来完成联动。下面是分步实现的方法:
第一步:添加后端API视图,返回指定制造商对应的类型列表
首先在你的views.py里新增一个视图函数,用来处理前端的请求,根据传入的制造商名称返回对应的Type数据:
from django.http import JsonResponse from django.core import serializers @login_required(login_url='/accounts/login/') def get_types_by_manufacturer(request): # 获取前端传入的制造商参数 manufacturer = request.GET.get('manufacturer', '') if not manufacturer or manufacturer == "All": # 如果选择"All"或无参数,返回所有类型 types = Type.objects.values_list('TypeName', flat=True).distinct() else: # 查询该制造商对应的所有零件,关联到对应的Type并去重 # 这里的关联逻辑需要匹配你的Model结构:假设Subtype外键指向Type,Part的Subtype关联Subtype types = Type.objects.filter( subtype__part__Manufacturer=manufacturer ).values_list('TypeName', flat=True).distinct() # 将结果转为JSON格式返回 return JsonResponse(list(types), safe=False)
然后在你的urls.py里添加这个视图的路由:
from django.urls import path from . import views urlpatterns = [ # 你的其他路由... path('get-types-by-manufacturer/', views.get_types_by_manufacturer, name='get_types_by_manufacturer'), ]
第二步:修改前端HTML,添加ID并编写联动JavaScript
先给下拉列表添加id属性,方便JS定位元素,再添加联动逻辑:
<div id="filterdiv" class="dark"> <center><h3>Filters</h3></center> <br> <center>Type</center> <!-- 给Type下拉框加id --> <select name="Types" id="type-select"> <option>All</option> {% for types in TypesList %} <option>{{types}}</option> {%endfor%} </select> <br> <br> <!-- 其他过滤项保持不变 --> <center>Manufacturer</center> <!-- 给Manufacturer下拉框加id --> <select name="Manufacturer" id="manufacturer-select"> <option>All</option> {% for manufacturers in ManufacturerList %} <option>{{manufacturers}}</option> {%endfor%} </select> <br> <br> <button>Apply Filter (TODO)</button> <button>Reset Filters (TODO)</button> </div> <!-- 添加JavaScript代码,放在页面底部 --> <script> // 获取两个下拉框元素 const manufacturerSelect = document.getElementById('manufacturer-select'); const typeSelect = document.getElementById('type-select'); // 拿到Django的CSRF令牌(默认开启CSRF保护时需要) const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; // 监听制造商下拉框的选择变化 manufacturerSelect.addEventListener('change', function() { const selectedManufacturer = this.value; // 发送请求到后端API fetch(`/get-types-by-manufacturer/?manufacturer=${encodeURIComponent(selectedManufacturer)}`, { headers: { 'X-CSRFToken': csrftoken } }) .then(response => response.json()) .then(types => { // 清空现有选项,保留"All" typeSelect.innerHTML = '<option>All</option>'; // 遍历返回的类型,添加新选项 types.forEach(type => { const option = document.createElement('option'); option.textContent = type; typeSelect.appendChild(option); }); }) .catch(error => { console.error('加载类型列表出错:', error); }); }); </script>
第三步:适配你的Model结构
注意后端视图里的查询语句Type.objects.filter(subtype__part__Manufacturer=manufacturer)是基于以下Model关联假设:
Subtype模型有一个外键指向TypePart模型的Subtype字段是指向Subtype的外键
如果你的Model关联方式不同,需要调整这个查询逻辑,确保能通过Manufacturer正确关联到对应的Type。
另外,如果你的过滤区域不在<form>标签内,需要手动添加CSRF令牌隐藏输入:
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
这样调整后,当你选择不同的Manufacturer时,Type下拉列表就会自动更新为对应的选项了。
内容的提问来源于stack exchange,提问作者CalMac
相关产品推荐
相关产品推荐

