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

Django新手求助:如何获取用户输入起止日期并查询数据库

搞定Django用户日期输入+数据库过滤的完整流程

嘿,作为Django新手碰到这个问题太正常啦!我来一步步带你搞定从用户那里获取起止日期,再用这些日期过滤数据库记录的全流程~

第一步:创建日期输入表单

首先你需要一个表单来让用户输入日期,Django的Form类能帮你轻松搞定输入验证和前端渲染。新建一个forms.py文件(如果还没有的话),写一个日期范围表单:

# forms.py
from django import forms
from django.utils import timezone

class DateRangeForm(forms.Form):
    from_date = forms.DateField(
        label='起始日期',
        widget=forms.DateInput(attrs={'type': 'date'}),
        initial=timezone.now().date() - timezone.timedelta(days=7)  # 默认设为7天前
    )
    to_date = forms.DateField(
        label='结束日期',
        widget=forms.DateInput(attrs={'type': 'date'}),
        initial=timezone.now().date()  # 默认设为今天
    )

这里用了type='date'的widget,前端会显示原生的日期选择器,用户输入更友好,还加了默认值提升体验。

第二步:在视图里处理表单和数据库查询

接下来在视图里处理两种请求:GET请求显示表单,POST请求接收用户提交的日期并过滤数据。假设你的模型是这样的(如果和你的模型不一样,替换成你的字段就行):

# models.py
from django.db import models
from django.utils import timezone

class Record(models.Model):
    title = models.CharField(max_length=100)
    created_at = models.DateTimeField(default=timezone.now)
    # 其他字段...

然后写视图函数:

# views.py
from django.shortcuts import render
from .models import Record
from .forms import DateRangeForm
from django.utils import timezone
from datetime import timedelta

def record_list(request):
    form = DateRangeForm(request.POST or None)
    records = Record.objects.all()  # 默认显示所有记录

    if request.method == 'POST' and form.is_valid():
        # 从表单获取清洗后的日期数据
        from_date = form.cleaned_data['from_date']
        to_date = form.cleaned_data['to_date']

        # 注意:如果你的字段是DateTimeField,要把结束日期转成次日凌晨,避免漏掉当天的记录
        end_date = to_date + timedelta(days=1)
        # 过滤数据库:created_at >= 起始日期 且 created_at < 次日凌晨
        records = Record.objects.filter(
            created_at__gte=timezone.make_aware(timezone.datetime.combine(from_date, timezone.datetime.min.time())),
            created_at__lt=timezone.make_aware(timezone.datetime.combine(end_date, timezone.datetime.min.time()))
        )

    return render(request, 'record_list.html', {'form': form, 'records': records})

这里有个小细节:如果你的模型字段是DateTimeField,直接用to_date的话,会漏掉当天23:59的记录,所以把结束日期加一天,用lt来过滤,这样更准确。如果你的字段是DateField,直接用created_at__range=(from_date, to_date)就行。

第三步:写模板渲染表单和结果

最后在模板里渲染表单和过滤后的记录,新建templates/record_list.html:

<!-- record_list.html -->
<!DOCTYPE html>
<html>
<head>
    <title>记录列表</title>
</head>
<body>
    <h1>按日期筛选记录</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">筛选</button>
    </form>

    <h2>筛选结果</h2>
    {% if records %}
        <ul>
            {% for record in records %}
                <li>{{ record.title }} - {{ record.created_at }}</li>
            {% endfor %}
        </ul>
    {% else %}
        <p>没有找到符合条件的记录</p>
    {% endif %}
</body>
</html>

用form.as_p快速渲染表单,加上{% csrf_token %}是Django必须的安全措施,然后循环显示过滤后的记录。

一些常见坑提醒

  • 时区问题:如果你的项目开启了时区(USE_TZ = True),记得用timezone.make_aware()把日期转成带时区的时间,不然会报错。
  • 表单验证:Django的Form会自动验证日期格式,用户输入无效日期的话,表单会显示错误提示,不用你自己写验证逻辑。
  • 默认值处理:如果用户没提交表单(第一次访问页面),会显示默认的日期范围和所有记录,你也可以改成默认显示最近7天的记录,只需要在GET请求时也执行过滤逻辑就行。

这样一套流程走下来,你就能轻松获取用户输入的日期并过滤数据库记录啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:05:13