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

Django中如何基于日期从DateTime字段的表中获取数据

Django按纯日期筛选DateTime类型字段数据解决方案

问题描述

表单提交纯日期数据(如from_date="2022-11-09"、to_date="2022-11-09"),但数据库表中created_at和updated_at字段为DateTime类型(包含日期与时间),需要在不修改表结构的前提下,实现按提交日期筛选对应数据。

用户原代码

views.py

from django.shortcuts import render
import pymysql
from django.http import HttpResponseRedirect
from facligo_app.models import Scrapper
from django.utils import timezone
import datetime
import pytz

find_description = ""
def index(request):
    if request.method == "POST":
        from_date = request.POST.get("from_date")
        print(from_date)
        to_date = request.POST.get("to_date")
        print(to_date)
        roles =  Scrapper.objects.all()
        # for i in roles:
        #     print(i.description)
        global find_description
        find_description = Scrapper.objects.all().filter(created_at=from_date,updated_at=to_date)
        print(find_description)

    return render(request, "home.html", {"scrappers": find_description})

models.py

from django.db import models
from django.db import connections
# Create your models here.
class Scrapper(models.Model):
    id = models.IntegerField(primary_key=True)
    full_name = models.CharField(max_length=100)
    slug = models.CharField(max_length=100)
    description = models.TextField(max_length=100)
    created_at = models.DateTimeField(default=True)
    updated_at = models.DateTimeField(default=True)
    class Meta:
        db_table = "test_table_1"

解决方案

直接用字符串日期匹配DateTime字段会失败,因为DateTime字段包含时间部分。可以通过以下两种方式实现筛选:

方法1:使用__date查询条件

Django ORM支持对DateTime字段使用__date后缀,直接匹配日期部分,无需转换日期格式:

find_description = Scrapper.objects.filter(
    created_at__date=from_date,
    updated_at__date=to_date
)

方法2:转换日期为DateTime范围(处理时区场景)

如果项目启用了时区(USE_TZ = True),建议将提交的日期转换为当日的起始和结束DateTime,避免时区偏差:

# 将字符串日期转为date对象
from_date_obj = datetime.datetime.strptime(from_date, "%Y-%m-%d").date()
to_date_obj = datetime.datetime.strptime(to_date, "%Y-%m-%d").date()

# 构造当日的起始和结束时间(带时区)
start_datetime = timezone.make_aware(datetime.datetime.combine(from_date_obj, datetime.time.min))
end_datetime = timezone.make_aware(datetime.datetime.combine(to_date_obj, datetime.time.max))

# 筛选created_at在当日范围内,且updated_at在当日范围内的数据
find_description = Scrapper.objects.filter(
    created_at__range=(start_datetime, end_datetime),
    updated_at__range=(start_datetime, end_datetime)
)

修改后的完整views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from facligo_app.models import Scrapper
from django.utils import timezone
import datetime

# 移除全局变量,改用局部变量避免并发污染
def index(request):
    scrappers = Scrapper.objects.all()  # 默认显示全部数据
    if request.method == "POST":
        from_date = request.POST.get("from_date")
        to_date = request.POST.get("to_date")
        if from_date and to_date:
            # 选用简洁的__date查询方式
            scrappers = Scrapper.objects.filter(
                created_at__date=from_date,
                updated_at__date=to_date
            )
    return render(request, "home.html", {"scrappers": scrappers})

注意事项

  • 若使用__date查询,需确保数据库支持该操作(MySQL、PostgreSQL等主流数据库均支持);
  • 启用时区时优先使用方法2,避免时区转换导致的日期匹配错误;
  • 原代码中的全局变量容易引发并发请求数据污染,改用局部变量更符合Django视图最佳实践。

内容的提问来源于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:15:32