【问题标题】:How can I filter by date, time and second in django?如何在 django 中按日期、时间和秒进行过滤?
【发布时间】:2020-10-25 19:49:46
【问题描述】:

在我的数据库中,我有很多不同日期的条目(包括时间、秒)。我需要找到所有最新的条目。

所以我尝试了:

    arr = balance_sheet.objects.all().values('timestump')
    date_arr=[]
    for text in arr:
        if text.get('timestump'):
            date_arr.append(text.get('timestump'))
    if date_arr:
        latest_date = max(date_arr)
    else:
        latest_date = datetime.datetime.now()
    latest = balance_sheet.objects.filter(timestump__icontains=latest_date)

但是在这种情况下latest 是空的。 但是如果我将最后一行更改为仅使用日期查询,它可以正常工作,但会返回当天的所有条目。

latest = balance_sheet.objects.filter(timestump__icontains=latest_date.date())

我需要找到所有最新的分:秒条目。最迟在最后一分钟进入。

我明白了:

2020-07-05 12:54:35.656849
2020-07-05 12:54:35.844049
2020-07-05 12:54:36.015650
2020-07-05 12:54:36.156050
2020-07-05 12:55:04.314099
2020-07-05 12:55:04.454500
2020-07-05 12:55:04.579300
2020-07-05 12:55:04.735300

我做错了吗?

我怎样才能只获得所有相同的分钟条目?如:

2020-07-05 12:55:04.314099
2020-07-05 12:55:04.454500
2020-07-05 12:55:04.579300
2020-07-05 12:55:04.735300

【问题讨论】:

  • 这不是按时间返回最新的对象吗? balance_sheet.objects.order_by('-timestump').first() ?
  • @ArakkalAbu 是的。谢谢你。我仍然想了解我问的事实。对于较大的数据库排序可能会减慢程序的速度。
  • @ArakkalAbu 但它只返回最后一个值。我有多个值作为最后一个条目。
  • @RafiSarker:不,根据所有记录手动确定最大值会慢 很多,因为它需要更多带宽,在 Python/Django 层进行处理,需要两次往返数据库等。

标签: python django filter django-queryset


【解决方案1】:

数据库可以返回最新的记录本身。例如,您可以使用.latest(…) [Django-doc]:

latest_sheet = balance_sheet.objects.<b>latest('timestump')</b>

这将导致如下查询:

SELECT *
FROM app_name.balance_sheet
ORDER BY timestump DESC
LIMIT 1

这将显着限制带宽,而且数据库已针对执行此类查询进行了优化。

然而,我们可以先获取最大的分钟:

from django.db.models import Max
from django.db.models.functions import ExtractMinute

latest_minute = balance_sheet.objects.aggregate(mx=Max(ExtractMinute('timestump'))['mx']
latest_sheets = balance_sheet.objects.annotate(
    mn=ExtractMinute('timestump')
).filter(mn=last_minute)

或者如果是最新截断的分钟:

from django.db.models import Max
from django.db.models.functions import TruncMinute

latest_minute = balance_sheet.objects.aggregate(mx=Max(TruncMinute('timestump'))['mx']
latest_sheets = balance_sheet.objects.annotate(
    mn=TruncMinute('timestump')
).filter(mn=last_minute)

balance_sheet 模型上添加数据库索引可能会有所帮助:

class balance_sheet(models.Model):
    # …
    timestump = models.DateTimeField(auto_now_add=True, db_index=True)

注意:通常是 Django 模型,就像 Python 中的所有类都以 PerlCase 命名,而不是 snake_case,所以它应该是:BalanceSheet 而不是 balance_sheet

【讨论】:

  • 使用latest 都不能解决问题。考虑一些条目,例如:2020-07-05 12:54:35.656849 2020-07-05 12:54:35.844049 2020-07-05 12:54:36.015650 2020-07-05 12:54:36.156050 2020-07-05 12:55:04.314099 2020-07-05 12:55:04.454500 2020-07-05 12:55:04.579300 2020-07-05 12:55:04.735300 这里所有日期都相同,但如果我们考虑分钟,则有两组条目。我需要最新的组。
  • @RafiSaker:那么它返回了什么,预期的结果是什么?
  • @RafiSaker:如果我在本地尝试这个,它会返回带有timestump = 2020-07-05 12:55:04.735300的对象。
  • 但我需要得到:2020-07-05 12:55:04.314099 2020-07-05 12:55:04.454500 2020-07-05 12:55:04.579300 2020-07-05 12:55:04.735300 因为,这些在 12:55:04 的所有条目都是通过循环一次性完成的。
  • @RafiSarker:__icontains 适用于字符串。因此,它会查看是否存在包含latest_date 的日期时间,但这只会返回完全匹配。它也将是完全不可扩展的,因为它在数据库和 Django/Python 层中都需要线性时间。该模块是functions 而不是function..
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2022-07-16
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
相关资源
最近更新 更多