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

Django中Datepicker日期区间选后表格不更新求助及无jQuery方案咨询

Django日期区间筛选表格无更新问题排查与无jQuery实现方案

问题描述

在Django项目中,已实现表格、数据展示表单及日历组件,但选择日期区间提交后,数据表格无任何变化。需要排查错误并获取无需jQuery的简化实现方案。

用户提供代码

models.py

from django.db import models

class EmployeeModel(models.Model):
    empid = models.IntegerField(primary_key=True)
    empname = models.CharField(max_length=50)
    salary = models.IntegerField()
    joindate = models.DateField()
    class Meta:
        db_table = "employee"

forms.py

from datetime import date
from django import forms
from .models import *

today = date.today()

class StockHistorySearchForm(forms.ModelForm):
    start_date = forms.DateField(required=False)
    end_date = forms.DateField(required=False)
    class Meta:
        model = EmployeeModel
        fields = ['start_date', 'end_date']

views.py

from django.shortcuts import render
from django_filters.views import FilterView
from django_tables2 import SingleTableMixin

# Create your views here.

from django.http import HttpResponse
from . import models
from .models import EmployeeModel

from .forms import StockHistorySearchForm

def showresults(request):
    header = "HYSTORY DATA"
    queryset = EmployeeModel.objects.all()
    form = StockHistorySearchForm(request.POST or None)
    context = {
        "header":header,
        "queryset":queryset,
        "form":form,
    }
    if request.method == "POST":
        queryset = EmployeeModel.objects.filter(
            joindate__range=[
                form['start_date'].value(),
                form['end_date'].value()
            ]
        )
    return render(request, "demo/index.html", context)

index.html

<!DOCTYPE html>
<html lang="en">
{% load static %}
{% load crispy_forms_tags %}
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link href="static/js/jquery-ui-1.13.2/jquery-ui.min.css" rel="stylesheet">
    <link href="static/js/jquery-ui-1.13.2/jquery-ui.structure.min.css" rel="stylesheet">
    <link href="static/js/jquery-ui-1.13.2/jquery-ui.theme.min.css" rel="stylesheet">

    <script src="static/js/jquery-3.6.3.min.js"></script>
    <script src="static/js/jquery-ui-1.13.2/jquery-ui.js"></script>
    <script src="static/js/myjs.js"></script>

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="header">{{header}}</div>
        <form method="POST" action="">
            {% csrf_token %}
            {{form|crispy}}
            <input type="submit" value="Search"/>
        </form>
        <hr/>
        <div class="display_table">
            <table class="table">
                <thead>
                    <tr>
                        <th>Employee Id</th>
                        <th>Employee Name</th>
                        <th>Salary</th>
                        <th>Join Date</th>
                    </tr>
                </thead>
                {% for instance in queryset %}
                <tr>
                    <td>{{ instance.empid }}</td>
                    <td>{{ instance.empname }}</td>
                    <td>{{ instance.salary }}</td>
                    <td>{{ instance.joindate }}</td>
                </tr>
                {% endfor %}
            </table>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js" integrity="sha384-mQ93GR66B00ZXjt0YO5KlohRA5SY2XofN4zfuZxLkoj1gXtW8ANNCe9d5Y3eG5eD" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
</body>
</html>

myjs.js

$(document).ready(function(){

  $(".datetimeinput").datepicker({changeYear: true,changeMonth: true, dateFormat: 'yy-mm-dd'});

});

错误排查建议

  • 表单验证缺失:当前视图未调用form.is_valid()验证数据,直接通过form['start_date'].value()取值可能得到无效数据。需先验证表单,再从cleaned_data获取值:
    if request.method == "POST":
        form = StockHistorySearchForm(request.POST)
        if form.is_valid():
            start_date = form.cleaned_data.get('start_date')
            end_date = form.cleaned_data.get('end_date')
            queryset = EmployeeModel.objects.all()
            if start_date and end_date:
                queryset = queryset.filter(joindate__range=[start_date, end_date])
    
  • 上下文更新滞后:初始queryset已放入context,POST请求中更新queryset后未同步更新context,导致模板仍使用原始数据。需在筛选完成后重新赋值到context。
  • 日期格式不匹配:前端日期控件格式为yy-mm-dd,需在表单字段中指定对应解析格式:
    start_date = forms.DateField(required=False, input_formats=['%Y-%m-%d'])
    end_date = forms.DateField(required=False, input_formats=['%Y-%m-%d'])
    
  • 空值未处理:若用户仅填写一个日期,joindate__range会因空值失效,需添加判断,仅当两个日期都存在时应用筛选。
  • 静态文件路径错误:前端静态文件使用相对路径,建议改用{% static %}标签生成正确路径,避免控件加载失败:
    <link href="{% static 'js/jquery-ui-1.13.2/jquery-ui.min.css' %}" rel="stylesheet">
    

无jQuery的简化实现方案

1. 前端用HTML5原生日期输入

直接使用HTML5的date类型输入框,浏览器自动提供日期选择器,无需jQuery:

  • 修改表单为普通Form(因start/end不是模型字段),指定输入控件类型:
    class StockHistorySearchForm(forms.Form):
        start_date = forms.DateField(required=False, widget=forms.DateInput(attrs={'type': 'date'}))
        end_date = forms.DateField(required=False, widget=forms.DateInput(attrs={'type': 'date'}))
    
  • 移除所有jQuery相关的CSS、JS引用。

2. 优化视图逻辑

改用GET请求提交筛选参数,方便用户保存链接或回退:

def showresults(request):
    header = "HISTORY DATA"
    queryset = EmployeeModel.objects.all()
    form = StockHistorySearchForm(request.GET or None)
    if form.is_valid():
        start_date = form.cleaned_data.get('start_date')
        end_date = form.cleaned_data.get('end_date')
        if start_date and end_date:
            queryset = queryset.filter(joindate__range=[start_date, end_date])
    context = {
        "header": header,
        "queryset": queryset,
        "form": form,
    }
    return render(request, "demo/index.html", context)

3. 简化模板

修改表单提交方式为GET,移除冗余引用:

<form method="GET">
    {{ form|crispy }}
    <input type="submit" value="Search" class="btn btn-primary"/>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:05:32