Skip to main content
 首页 » 编程设计

python之Django 按时间过滤日期时间字段,不考虑日期

2025年05月04日27zhujiabin

我在 Django 中有一个日期时间字段,我想根据时间过滤它。我不关心具体日期,但我想查找 7:30 之前的所有交易,例如。

我知道我可以按小时和分钟过滤,例如:

Q(datetime__hour=7) & \ 
Q(datetime__minute=30) 

但是,这会在 7:30 找到所有交易。您也无法申请 gte 或 lte。即

(Q(datetime__hour__lte=7) & \ 
Q(datetime__minute__lte=30)) | \ 
Q(datetime__hour__lt=7) 

唯一似乎是潜在解决方案的是有很多查询,例如:

(Q(datetime__hour=7) & \ 
(Q(datetime__minute=30) | \ 
 Q(datetime__minute=29) | \ 
 Q(datetime__minute=28) | \ 
 .... 
 Q(datetime__minute=2) | \ 
 Q(datetime__minute=1) | \ 
 Q(datetime__minute=0))) | \ 
Q(datetime__hour=6) | \ 
Q(datetime__hour=5) | \ 
Q(datetime__hour=4) | \ 
Q(datetime__hour=3) | \ 
Q(datetime__hour=2) | \ 
Q(datetime__hour=1) | \ 
Q(datetime__hour=0) 

但这看起来很荒谬。

有人有什么想法吗?

请您参考如下方法:

只需将日期时间字段拆分为日期和时间字段即可。比你只能按时间过滤:

from datetime import combine 
 
class MyModel(models.Model): 
    start_date = models.DateField() 
    start_time = models.TimeField() 
 
    class Meta: 
        ordering = ['start_date', 'start_time'] 
 
    def start_datetime(self): 
        return combine(self.date, self.time) 

我添加了 Meta.ordering 和 start_datetime 模型方法,以表明该模型能够以与具有 DateTimeField 的模型相同的方式呈现数据。

现在您可以按时间过滤:

objects = MyModel.objects.filter(start_time__lt=time(7, 30)) 

更新

如果您有一个已建立的项目,并且许多查询都依赖于普通的 DateTime 字段。将日期时间拆分为日期和时间字段是有代价的:重写查询会使您的项目失败。有一个替代方案:只添加一个时间字段并保持日期时间字段不变。保存方法可以根据日期时间添加时间。不利的一面是您的数据库中有重复的数据。好处是它可以用最少的努力解决您的问题。

class MyModel(models.Model): 
    start_datetime = models.DateTimeField() 
    start_time = models.TimeField(blank=True) 
 
    def save(self) 
        self.start_time = self.start_datetime.time 

所有现有查询将与以前相同,并且仅按时间过滤:

objects = MyModel.objects.filter(start_time__lt=time(7, 30))