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

如何在Django中实现Ajax校验日期冲突后确认保存功能

需求

点击表单提交按钮时,通过Ajax检查数据库中是否存在日期交集;仅当用户确认仍要添加时,才将数据保存至数据库并跳转至其他页面。当前仅实现了弹出alert提示的功能。

现有代码

Komandirov_add.html

<form method="post" id="contactForm">
    {% csrf_token %}
    {% if form.warnings %}
        <div class="rounded p-2 mt-2 bg-warning">
            <ul>
                {% for warning in form.warnings %}
                    <li><b>{{ warning.message }}:</b> {{ warning.description }}</li>
                {% endfor %}
            </ul>
        </div>
    {% endif %}
    <div style="display: flex;flex-wrap: wrap;">
        {{ form.NumberKU.label_tag }}{{ form.NumberKU }}
        {% if form.NumberKU.errors %}
            <div class="error">{{ form.NumberKU.errors }}</div>
        {% endif %}
    </div>
<input id='d' type="submit" onclick="reload_page(); return false;" value="Сохранить">


</form>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {

      
        $('#contactForm').submit(function () {
            $.ajaxSetup({
                headers: {
                    "X-CSRFToken": document.querySelector('[name=csrfmiddlewaretoken]').value,
                }
            });
       
            $.ajax({
                data: $(this).serialize(),
                url: "{% url 'prikaz:komandirov_add' human.pk %}",
                type: $(this).attr('method'),
              
                success: function (response) {

                    console.log(response.f)
                    if (response.f == 'f') {
                        alert('dd');
                        window.location.href = "{% url 'prikaz:komandirov' human.pk %}";
                    } else{
                         window.location.href = "{% url 'prikaz:komandirov' human.pk %}";
                    }
                },
                
            });
            return false;
        });
    })

</script>

urls.py

urlpatterns = [
    path('human/<int:id>/komandirov/komandirov_add/', views.KomandirovAdd.as_view(), name='komandirov_add'),
]

views.py

class KomandirovAdd(FormView):  
    form_class = KomandirovForm
    template_name = 'prikaz/block_content/Komandirov_add.html'

    # context_object_name = 'form'

    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['human'] = Privatedata.objects.get(id=self.kwargs['id'])
        return context

    def form_valid(self, form):
        print(form.cleaned_data)
        addindb = form.save(commit=False)
        addindb.People = Privatedata.objects.get(id=self.kwargs['id'])
        addindb.save()
        overlapping_records = Otpysk.objects.filter(
            Q(DateUbitie__range=(form.cleaned_data['DateUbitie'], form.cleaned_data['DataPredpol'])) & Q(
                DataPredpol__range=(form.cleaned_data['DateUbitie'], form.cleaned_data['DataPredpol'])))
        if len(overlapping_records) > 0:
            return JsonResponse({'f':'f'})
        else:
            return JsonResponse({'f':'d'})
    
    def get_success_url(self):
        return reverse_lazy("prikaz:komandirov", args=[self.kwargs['id']])

修改方案

前端修改

  • 替换alert为确认对话框,根据用户选择决定是否提交强制保存请求:
$(document).ready(function () {
    $('#contactForm').submit(function (e) {
        e.preventDefault();
        const form = $(this);
        $.ajaxSetup({
            headers: {
                "X-CSRFToken": document.querySelector('[name=csrfmiddlewaretoken]').value,
            }
        });
        // 第一步:检查日期交集
        $.ajax({
            data: form.serialize(),
            url: "{% url 'prikaz:komandirov_add' human.pk %}",
            type: form.attr('method'),
            dataType: 'json',
            success: function (response) {
                if (response.has_overlap) {
                    // 弹出确认框询问用户
                    const confirmSave = confirm('检测到日期交集,是否仍要添加该记录?');
                    if (confirmSave) {
                        // 用户确认,携带强制保存参数重新提交
                        $.ajax({
                            data: form.serialize() + '&force_save=true',
                            url: "{% url 'prikaz:komandirov_add' human.pk %}",
                            type: form.attr('method'),
                            success: function () {
                                window.location.href = "{% url 'prikaz:komandirov' human.pk %}";
                            }
                        });
                    }
                    // 用户取消则不执行任何操作
                } else {
                    // 无交集,直接跳转
                    window.location.href = "{% url 'prikaz:komandirov' human.pk %}";
                }
            },
        });
    });
})
  • 移除提交按钮上的冲突事件:
<input id='d' type="submit" value="Сохранить">

后端修改

  • 调整逻辑,先检查交集再根据参数决定是否保存,同时修正交集查询逻辑:
from django.http import JsonResponse

class KomandirovAdd(FormView):  
    form_class = KomandirovForm
    template_name = 'prikaz/block_content/Komandirov_add.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['human'] = Privatedata.objects.get(id=self.kwargs['id'])
        return context

    def form_valid(self, form):
        # 修正日期交集查询逻辑,用|代替&才能正确检测重叠
        overlapping_records = Otpysk.objects.filter(
            Q(DateUbitie__range=(form.cleaned_data['DateUbitie'], form.cleaned_data['DataPredpol'])) |
            Q(DataPredpol__range=(form.cleaned_data['DateUbitie'], form.cleaned_data['DataPredpol']))
        )
        has_overlap = len(overlapping_records) > 0

        # 第一次请求仅返回交集状态,不保存数据
        if 'force_save' not in self.request.POST:
            return JsonResponse({'has_overlap': has_overlap})
        
        # 有强制保存参数时,执行保存
        addindb = form.save(commit=False)
        addindb.People = Privatedata.objects.get(id=self.kwargs['id'])
        addindb.save()
        return JsonResponse({'success': True})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:09:52