在 Django 中,如何构建我的查询集以在时间片上按时间进行过滤?
In Django, how do I construct my queryset to filter by time over slices of time?
我正在使用 Python 3.9 和 Django 3.2。我有这个价格型号
class Price(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
price = models.FloatField(null=False)
created = models.DateTimeField(null=False, default=datetime.now)
如果我想获得过去 24 小时内每小时的价格,我可以运行这样的方法
def _get_prices_per_time_slice(self, last_hours=24):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time],
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
但假设我想每隔 X 小时获取一次价格。
def _get_prices_per_time_slice(self, last_hours=24, time_slice_in_hours=4):
所以如果当前时间是午夜(零秒和零分),我想获得午夜、晚上 8 点、下午 4 点、中午、早上 8 点和凌晨 4 点的价格。如何添加过滤器以每隔 X 小时筛选一次价格?
python中的range函数有助于指定增量步长值
语法:range(start, stop, step)
x = range(3, 20, 4)
for n in x:
print(n)
#Gives output
>>> 3
>>> 7
>>> 11
>>> 15
>>> 19
只需重写created_range
增加步长值time_slice_in_hours
created__range=[start_time, end_time, time_slice_in_hours]
选项 1
def _get_prices_per_time_slice(self, last_hours= 24,time_slice_in_hours=4):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time, time_slice_in_hours],
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
然而 django query set api official documentation 中的语法未能在 __range()
函数中提及步骤参数,即 created__range
可能不支持它。
选项 2
在这种情况下,您可以使用下面的函数,您可以使用 Python 的 DateTimeRange
函数(official documentation)计算时间范围 x_time_slice_list
并评估为 created__in
from datetimerange import DateTimeRange
from dateutil.relativedelta import relativedelta
def _get_prices_per_time_slice(self, last_hours= 24,time_slice_in_hours=4):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
x_time_slice_list= []
time_range = DateTimeRange(start_time, end_time)
for value in time_range.range(relativedelta(hours=+time_slice_in_hours)):
x_time_slice_list.append(value)
qset = Price.objects.filter(
created__in= x_time_slice_list,
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
您可以通过在 python 中处理时间片过滤来实现此目的。
我的意思是如果你把你有的功能拿过来。即
def _get_prices_per_time_slice(self, last_hours=24):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time],
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
并按照您的方式将其重写为 return 创建的数据并处理 return 列表理解中的过滤。
def _get_prices_per_time_slice(self, last_hours=24, time_slice_in_hours=4):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time],
created__minute=end_time.minute
).values('price', 'created')
return [r.get('price') for r in qset if r.get('created').hour % time_slice_in_hours == 0]
我正在使用 Python 3.9 和 Django 3.2。我有这个价格型号
class Price(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
price = models.FloatField(null=False)
created = models.DateTimeField(null=False, default=datetime.now)
如果我想获得过去 24 小时内每小时的价格,我可以运行这样的方法
def _get_prices_per_time_slice(self, last_hours=24):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time],
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
但假设我想每隔 X 小时获取一次价格。
def _get_prices_per_time_slice(self, last_hours=24, time_slice_in_hours=4):
所以如果当前时间是午夜(零秒和零分),我想获得午夜、晚上 8 点、下午 4 点、中午、早上 8 点和凌晨 4 点的价格。如何添加过滤器以每隔 X 小时筛选一次价格?
python中的range函数有助于指定增量步长值
语法:range(start, stop, step)
x = range(3, 20, 4)
for n in x:
print(n)
#Gives output
>>> 3
>>> 7
>>> 11
>>> 15
>>> 19
只需重写created_range
增加步长值time_slice_in_hours
created__range=[start_time, end_time, time_slice_in_hours]
选项 1
def _get_prices_per_time_slice(self, last_hours= 24,time_slice_in_hours=4):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time, time_slice_in_hours],
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
然而 django query set api official documentation 中的语法未能在 __range()
函数中提及步骤参数,即 created__range
可能不支持它。
选项 2
在这种情况下,您可以使用下面的函数,您可以使用 Python 的 DateTimeRange
函数(official documentation)计算时间范围 x_time_slice_list
并评估为 created__in
from datetimerange import DateTimeRange
from dateutil.relativedelta import relativedelta
def _get_prices_per_time_slice(self, last_hours= 24,time_slice_in_hours=4):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
x_time_slice_list= []
time_range = DateTimeRange(start_time, end_time)
for value in time_range.range(relativedelta(hours=+time_slice_in_hours)):
x_time_slice_list.append(value)
qset = Price.objects.filter(
created__in= x_time_slice_list,
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
您可以通过在 python 中处理时间片过滤来实现此目的。
我的意思是如果你把你有的功能拿过来。即
def _get_prices_per_time_slice(self, last_hours=24):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time],
created__minute=end_time.minute
).values('price')
return [r['price'] for r in qset]
并按照您的方式将其重写为 return 创建的数据并处理 return 列表理解中的过滤。
def _get_prices_per_time_slice(self, last_hours=24, time_slice_in_hours=4):
now = timezone.now()
end_time = now.replace(second = 0, microsecond = 0)
start_time = end_time - timedelta(hours=last_hours)
qset = Price.objects.filter(
created__range=[start_time, end_time],
created__minute=end_time.minute
).values('price', 'created')
return [r.get('price') for r in qset if r.get('created').hour % time_slice_in_hours == 0]