Django中如何通过POST请求筛选指定日期的表格数据
问题解决:Django日期筛选及分页优化
问题原因分析
- 日期匹配逻辑错误:原代码直接用
created_at=from_date做精确匹配,但Django的DateTimeField存储带时分秒的完整时间,而表单提交的是纯日期字符串,仅能匹配当天0点整的记录,无法覆盖全天数据。 - 分页丢失筛选状态:POST提交筛选条件后,分页链接是GET请求,未携带日期参数,翻页后会回到全量数据展示。
- 代码冗余:POST和GET分支的分页逻辑重复,可合并复用。
修正后的代码
views.py
from django.db.models import Q from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import render def home(request): # 兼容POST提交和GET分页时的日期参数 from_date = request.POST.get("from_date") or request.GET.get("from_date") to_date = request.POST.get("to_date") or request.GET.get("to_date") # 初始化查询集 scrapper_list = Scrapper.objects.all() # 应用日期范围筛选:匹配created_at或updated_at在指定日期区间内的数据 if from_date and to_date: scrapper_list = scrapper_list.filter( Q(created_at__date__gte=from_date) & Q(created_at__date__lte=to_date) | Q(updated_at__date__gte=from_date) & Q(updated_at__date__lte=to_date) ) # 若需同时满足created_at和updated_at都在区间内,替换为以下filter: # scrapper_list = scrapper_list.filter( # created_at__date__gte=from_date, # created_at__date__lte=to_date, # updated_at__date__gte=from_date, # updated_at__date__lte=to_date # ) # 处理分页逻辑 page = request.GET.get('page', 1) paginator = Paginator(scrapper_list, 5) try: users = paginator.page(page) except PageNotAnInteger: users = paginator.page(1) except EmptyPage: users = paginator.page(paginator.num_pages) # 传递参数到模板,用于分页链接和表单回显 context = { 'users': users, 'from_date': from_date, 'to_date': to_date } return render(request, "home.html", context)
home.html
<!DOCTYPE html> <html> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> <body> <style> h2 {text-align: center;} </style> <h1>Facilgo Completed Jobs</h1> <form action="" method="post"> {% csrf_token %} <label for="from_date">From Date:</label> <!-- 回显已选择的日期 --> <input type="date" id="from_date" name="from_date" value="{{ from_date|default:'' }}"> <label for="to_date">To Date:</label> <input type="date" id="to_date" name="to_date" value="{{ to_date|default:'' }}"> <input type="submit"><br> </form> <div class="container"> <div class="row"> <div class="col-md-12"> <h2>Summary Details</h2> <table id="bootstrapdatatable" class="table table-striped table-bordered" width="100%"> <thead> <tr> <th>user_registration_source_id</th> <th>user_type</th> <th>user_id</th> <th>source</th> <th>source_url</th> <th>created at</th> <th>updated at</th> </tr> </thead> <tbody> {% for stud in users %} <tr> <td>{{stud.user_registration_source_id}}</td> <td>{{stud.user_type}}</td> <td>{{stud.user_id}}</td> <td>{{stud.source}}</td> <td>{{stud.source_url}}</td> <td>{{stud.created_at}}</td> <td>{{stud.updated_at}}</td> </tr> {% endfor %} </tbody> </table> {% if users.has_other_pages %} <ul class="pagination"> {% if users.has_previous %} <li><a href="?page={{ users.previous_page_number }}{% if from_date %}&from_date={{ from_date }}{% endif %}{% if to_date %}&to_date={{ to_date }}{% endif %}">«</a></li> {% else %} <li class="disabled"><span>«</span></li> {% endif %} {% if users.number|add:'-4' > 1 %} <li><a href="?page={{ users.number|add:'-5' }}{% if from_date %}&from_date={{ from_date }}{% endif %}{% if to_date %}&to_date={{ to_date }}{% endif %}">…</a></li> {% endif %} {% for i in users.paginator.page_range %} {% if users.number == i %} <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li> {% elif i > users.number|add:'-5' and i < users.number|add:'5' %} <li><a href="?page={{ i }}{% if from_date %}&from_date={{ from_date }}{% endif %}{% if to_date %}&to_date={{ to_date }}{% endif %}">{{ i }}</a></li> {% endif %} {% endfor %} {% if users.has_next %} <li><a href="?page={{ users.next_page_number }}{% if from_date %}&from_date={{ from_date }}{% endif %}{% if to_date %}&to_date={{ to_date }}{% endif %}">»</a></li> {% else %} <li class="disabled"><span>»</span></li> {% endif %} </ul> {% endif %} </div> </div> </div> </body> </html>
核心修正点
- 日期范围筛选:使用
__date提取日期部分,结合gte/lte实现区间匹配,覆盖全天数据。 - 保留筛选状态:分页链接拼接
from_date和to_date参数,确保翻页时筛选条件不丢失。 - 表单回显:日期输入框回显已选值,提升用户体验。
- 代码复用:合并POST和GET分支的分页逻辑,减少冗余。
内容的提问来源于stack exchange,提问作者Ajay
相关产品推荐
相关产品推荐

