Django views.py如何获取HTML下拉框选中option的文本作为变量
Django 三级联动下拉框选中项文本获取方案
现有问题梳理
- 模型层基于Django ORM定义
State(州,36条数据)、District(区县,706条数据,外键关联State)、Block(区块,约7000条数据,外键关联District)三张表,层级关系清晰 - 模板层下拉框
option属性绑定逻辑错误:区县、区块下拉框的value属性存的是上级关联字段值,而非当前选项的唯一标识,导致表单提交后无法定位具体选中项 - 视图层仅能通过
request.POST.get获取option的value值,无法直接拿到选项显示文本 - 现有jQuery联动逻辑仅覆盖州-区县两级,区县-区块第三级联动失效
具体实现方案
1. 修正模板层下拉框绑定逻辑
将每个下拉框option的value属性绑定当前选项的主键ID,显示文本正常放在标签内部即可,不要在value里存储上级关联字段:
<select id="state" name="state_id"> <option value="">请选择州</option> {% for state in state_list %} <option value="{{ state.id }}">{{ state.name }}</option> {% endfor %} </select> <select id="district" name="district_id"> <option value="">请选择区县</option> </select> <select id="block" name="block_id"> <option value="">请选择区块</option> </select>
表单默认提交规则:只会提交选中option的value属性值,上级关联逻辑不需要通过value传值,由前端联动逻辑动态处理即可。
2. 修复jQuery三级联动逻辑
采用按需加载的方式拉取下级选项,不要一次性渲染7000条区块数据造成页面卡顿:
$(function () { // 监听州选择事件,加载对应区县 $('#state').on('change', function () { const stateId = $(this).val(); // 重置下级下拉框 $('#district').html('<option value="">请选择区县</option>'); $('#block').html('<option value="">请选择区块</option>'); if (!stateId) return; // 请求对应区县数据 $.get('/api/district/', {state_id: stateId}, function (res) { res.data.forEach(item => { $('#district').append(`<option value="${item.id}">${item.name}</option>`); }) }) }) // 监听区县选择事件,加载对应区块 $('#district').on('change', function () { const districtId = $(this).val(); $('#block').html('<option value="">请选择区块</option>'); if (!districtId) return; // 请求对应区块数据 $.get('/api/block/', {district_id: districtId}, function (res) { res.data.forEach(item => { $('#block').append(`<option value="${item.id}">${item.name}</option>`); }) }) }) })
3. 视图层获取选中项显示文本
不要依赖前端传递显示文本,拿到提交的主键ID后直接通过ORM查询对应名称即可,从根源避免前端传值被篡改的问题:
# views.py from django.http import JsonResponse from .models import State, District, Block # 区县数据接口 def get_district(request): state_id = request.GET.get('state_id') district_list = District.objects.filter(state_id=state_id).values('id', 'name') return JsonResponse({'code': 0, 'data': list(district_list)}) # 区块数据接口 def get_block(request): district_id = request.GET.get('district_id') block_list = Block.objects.filter(district_id=district_id).values('id', 'name') return JsonResponse({'code': 0, 'data': list(block_list)}) # 表单提交处理 def form_submit(request): if request.method == 'POST': state_id = request.POST.get('state_id') district_id = request.POST.get('district_id') block_id = request.POST.get('block_id') # 直接通过主键查询获取显示文本 state_name = State.objects.filter(id=state_id).first().name if state_id else '' district_name = District.objects.filter(id=district_id).first().name if district_id else '' block_name = Block.objects.filter(id=block_id).first().name if block_id else '' # 后续业务逻辑处理
特殊场景处理:如果必须从前端直接获取选中项文本(不推荐),可以新增隐藏input标签,通过jQuery监听select选中事件,将选中项的text值赋值给隐藏input,视图层直接通过
request.POST.get取隐藏input对应name的值即可。
内容的提问来源于stack exchange,提问作者Abhilash Singh Chauhan
相关产品推荐
相关产品推荐

