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

Django使用Ajax实现表单自动填充时元素重复及选中值保留问题

问题根因

你现在遇到元素重复的核心原因是:Ajax请求触发后,后端返回了完整的页面模板(包含外层标题、页面结构),而你直接把整个返回内容替换到了现有<form>标签内部,相当于把完整页面嵌套进了表单里,自然会出现重复元素。


解决方案

1. 拆分表单模板

先把表单的核心字段部分抽成独立的局部模板,命名为_well_form_fields.html,仅保留表单内部的核心内容,不要外层页面结构:

{% load crispy_forms_tags %}
{% csrf_token %}
<div class="border p-2 mb-3 mt-3 border-secondary">
    <div class="form-row">
        <div id= "PUITS" class="form-group col-md-3 mb-0">
            {{form.PUITS|as_crispy_field}}
        </div>
        <div class="form-group col-md-3 mb-0">
            {{ form.CS |as_crispy_field}}
        </div>
        <div class="form-group col-md-3 mb-0">
            {{ form.MODE|as_crispy_field}}
        </div>
        <div class="form-group col-md-3 mb-0">
            {{ form.SITUATION |as_crispy_field}}
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-3 mb-0">
            {{ form.DATE_TEST|as_crispy_field }}
        </div>
        <div id='DUSE' class="form-group col-md-3 mb-0">
           {{ form.DUSE|as_crispy_field }}
        </div>
        <div class="form-group col-md-3 mb-0">
            {{ form.PRES_TBG|as_crispy_field }}
        </div>
        <div class="form-group col-md-3 mb-0">
            {{ form.PRES_CSG|as_crispy_field }}
        </div>
    </div>     
    <div class="form-row">
        <div class="form-group col-md-8 mb-0">
            {{ form.OBSERVATION|as_crispy_field }}
        </div>
    </div>
</div>
<input class="btn btn-success mb-4" type="submit" value="ADD Record">

修改原来的完整页面模板Add_wellMntr2.html,在表单内部新增一个容器用来包裹动态加载的字段部分,引用刚才的局部模板:

<!-- 原有外层页面结构保持不变 -->
<form method="POST" id="SurveillanceDesPuits_F" data-record-url="{% url 'Add_wellMntr' %}">
    <!-- 新增容器用于动态替换 -->
    <div id="form-fields-wrapper">
        {% include 'measure/Surveill_Wells/_well_form_fields.html' %}
    </div>
</form>
<!-- 原有script部分保持不变,后续会修改Ajax逻辑 -->

2. 修改后端视图逻辑

调整CreateWellMon函数,区分普通页面请求和Ajax请求,Ajax请求只返回局部模板内容:

from django.core.exceptions import ObjectDoesNotExist

def CreateWellMon(request):
    if request.method == 'POST':
        form = SurveillanceDesPuits_F(request.POST or None)
        if form.is_valid():
            form.instance.author = request.user
            form.save()
            return redirect('WellMonitor')
    else:
        form = None
        try:
            PUITS_id = request.GET.get('PUITS')
            # 按id倒序取对应井的最新记录
            record = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id).order_by('-id').first()
            if not record:
                raise ObjectDoesNotExist
            form = SurveillanceDesPuits_F(instance=record)
        except ObjectDoesNotExist:
            # 取不到对应井记录时取全表最新记录
            latest_record = SurveillanceDesPuits.objects.all().order_by('-id').first()
            form = SurveillanceDesPuits_F(instance=latest_record)
        # 判断是否为Ajax请求
        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            # Ajax请求返回局部表单模板
            return render(request, 'measure/Surveill_Wells/_well_form_fields.html', {'form': form})
        # 普通请求返回完整页面
        return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})

3. 调整前端Ajax逻辑

修改JS代码,仅替换表单字段容器的内容,不要替换整个form标签,同时改用事件委托保证动态加载后的下拉框事件正常触发:

$(document).ready(function(){
    // 事件委托适配动态加载的表单元素
    $(document).on('change', "#id_PUITS", function(){
        var url = $("#SurveillanceDesPuits_F").attr("data-record-url");  
        var PUITSId = $(this).val();
        $.ajax({ 
            type: 'GET',               
            url: url,              
            data: {'PUITS': PUITSId},
            success: function (data){
                // 只替换字段容器内容,不会引入外层页面结构避免重复
                $('#form-fields-wrapper').html(data);
                // 后端返回的form已经绑定了选中井的对应记录,下拉框会自动保留选中值,无需额外处理
            }
        });
        return false;
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:36:03