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

Django中如何通过POST请求筛选指定日期的表格数据

问题解决:Django日期筛选及分页优化

问题原因分析

  1. 日期匹配逻辑错误:原代码直接用created_at=from_date做精确匹配,但Django的DateTimeField存储带时分秒的完整时间,而表单提交的是纯日期字符串,仅能匹配当天0点整的记录,无法覆盖全天数据。
  2. 分页丢失筛选状态:POST提交筛选条件后,分页链接是GET请求,未携带日期参数,翻页后会回到全量数据展示。
  3. 代码冗余: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>

核心修正点

  1. 日期范围筛选:使用__date提取日期部分,结合gte/lte实现区间匹配,覆盖全天数据。
  2. 保留筛选状态:分页链接拼接from_date和to_date参数,确保翻页时筛选条件不丢失。
  3. 表单回显:日期输入框回显已选值,提升用户体验。
  4. 代码复用:合并POST和GET分支的分页逻辑,减少冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:05:28