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
相关产品推荐
相关产品推荐

