[英]Django filter datetime field by time, irrespective of date
I have a datetime field in Django, and I want to filter this based on time.我在 Django 中有一个日期时间字段,我想根据时间过滤它。 I don't care about the particular date, but I want to find all transactions before 7:30, for example.
我不关心特定日期,但我想查找 7:30 之前的所有交易,例如。
I know I can filter by hour and minute such as:我知道我可以按小时和分钟过滤,例如:
Q(datetime__hour=7) & \
Q(datetime__minute=30)
However, this would find all transactions AT 7:30.但是,这会在 7:30 找到所有交易。 You are also unable to apply gte or lte.
您也无法申请 gte 或 lte。 ie
IE
(Q(datetime__hour__lte=7) & \
Q(datetime__minute__lte=30)) | \
Q(datetime__hour__lt=7)
The only thing that appears to be a potential solution is to have many queries, such as:唯一似乎是潜在解决方案的是有许多查询,例如:
(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)
But this seems ridiculous.但这似乎很荒谬。
Anyone have any ideas?有人有主意吗?
Just split the datetime field into a date and a time field.只需将日期时间字段拆分为日期和时间字段即可。 Than you can filter on time only:
比你只能按时过滤:
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)
I added the Meta.ordering and start_datetime model method to show that this model can present data in the same way a model with a DateTimeField can.我添加了 Meta.ordering 和 start_datetime model 方法来表明这个 model 可以像带有 DateTimeField 的 model 一样呈现数据。
Now you can filter on time:现在您可以按时过滤:
objects = MyModel.objects.filter(start_time__lt=time(7, 30))
If you have a established project and many queries depend on having a normal DateTime field.如果您有一个已建立的项目并且许多查询都依赖于具有正常的 DateTime 字段。 Splitting the datetime into a date and time fields come a cost: Rewriting queries threw out your project.
将日期时间拆分为日期和时间字段是有代价的:重写查询会使您的项目失败。 There is an alternative: Only add a time field and leave the datetime field untouched.
有一个替代方案:只添加一个时间字段并保持日期时间字段不变。 A save method can add the time based on datetime.
保存方法可以根据日期时间添加时间。 The down side is that you have duplicated data in your db.
不利的一面是您的数据库中有重复的数据。 The good thing it solves your problem with minimal effort.
好处是它可以以最小的努力解决您的问题。
class MyModel(models.Model):
start_datetime = models.DateTimeField()
start_time = models.TimeField(blank=True)
def save(self)
self.start_time = self.start_datetime.time
All existing queries will be the same as before and filter on time only:所有现有查询都将与以前相同,并且仅按时间过滤:
objects = MyModel.objects.filter(start_time__lt=time(7, 30))
In Django 1.7+ you could use a transform to extract minute and hour from the timestamp.在 Django 1.7+ 中,您可以使用转换从时间戳中提取分钟和小时。 See https://docs.djangoproject.com/en/1.7/howto/custom-lookups/#a-simple-transformer-example for details.
有关详细信息,请参阅https://docs.djangoproject.com/en/1.7/howto/custom-lookups/#a-simple-transformer-example 。
Not sure when the filter by time was introduced, but in recent versions of Django (4.0+) this is done by the following query syntax:不确定何时引入按时间筛选,但在 Django (4.0+) 的最新版本中,这是通过以下查询语法完成的:
YourModel.objects.all().filter(datetime__hour__lte=7, datetime__minute__lte=30)
Where YourModel
is the model you are filtering, and datetime
is the field from that model.其中
YourModel
是您要过滤的 model, datetime
是来自该 model 的字段。
Ideas:想法:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.