Django过滤今天发生的事件

ktecyv1j  于 2023-05-19  发布在  Go
关注(0)|答案(9)|浏览(150)

我正在努力在Django过滤器中逻辑地表示以下内容。我有一个“事件”模型和一个位置模型,可以表示为:

class Location(models.Model):
    name = models.CharField(max_length=255)

class Event(models.Model):
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()
    location = models.ForeignKeyField(Location)

    objects = EventManager()

对于给定的位置,我想选择今天发生的所有事件。我已经尝试了各种策略,通过EventManager中的'bookings_today'方法,但正确的过滤器语法让我感到困惑:

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        bookings = self.filter(location=location_id, start=?, end=?)

date()失败,因为这会将时间归零,一天中的时间对应用程序至关重要,对于日期的最小值和最大值也是如此,并将它们用作书挡。此外,还有多种可能的有效配置:

start_date < today, end_date during today
start_date during today, end_date during today
start_date during today, end_date after today

我是否需要编写一整套不同的选项,或者是否有更简单和优雅的方法?

g0czyy6m

g0czyy6m1#

您需要两个不同的datetime阈值-today_starttoday_end

from datetime import datetime, timedelta, time

today = datetime.now().date()
tomorrow = today + timedelta(1)
today_start = datetime.combine(today, time())
today_end = datetime.combine(tomorrow, time())

今天发生的任何事情都必须在 * today_end**之前开始,**在 * today_start之后结束,所以:

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        # Construction of today_end / today_start as above, omitted for brevity
        return self.filter(location=location_id, start__lte=today_end, end__gte=today_start)

(P.S.将DateTimeField(而不是DateField)称为foo_date是令人恼火的误导-仅考虑startend...)

wlzqhblo

wlzqhblo2#

我看到的答案都没有时区意识。
你为什么不这样做呢

from django.utils import timezone

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        bookings = self.filter(location=location_id, start__gte=timezone.now().replace(hour=0, minute=0, second=0), end__lte=timezone.now().replace(hour=23, minute=59, second=59))
laawzig2

laawzig23#

你需要像这样使用一个范围:

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        from datetime import datetime
        now = datetime.now()
        bookings = self.filter(location=location_id, start__lte=now, end__gte=now)
        return bookings
yhxst69z

yhxst69z4#

timezone.localtime(timezone.now()).date()获取正确的日期。
要获取今天发生的事件(start today),请执行以下操作:

from django.utils import timezone

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        t = timezone.localtime(timezone.now())
        bookings = self.filter(location=location_id, start__year = t.year,
            start__month = t.month, start__day = t.day, )
ghhaqwfi

ghhaqwfi5#

因为它是一个DateTimeField使用start_date__date

from django.utils import timezone

today = timezone.now().date()
leave = Event.objects.filter(start_date__date=today)
oxosxuxt

oxosxuxt6#

我想排除是你的朋友!

today = datetime.date.today()
tomorrow = today + datetime.timedelta( days = 1 )
self.filter( location = location_id ).exclude( end_date__lt = today ).exclude( start_date__gte = tomorrow )
xnifntxz

xnifntxz7#

不如这样:pub_date__gte=datetime(2005, 1, 1)?使用_gte__lte,使用链接方法将开始和结束限制在一天内。
比如self.filter(start__gte=datetime(2005, 1, 1)).filter(end__lte=datetime(2005, 1, 1))lte表示小于等于,gte表示大于等于。
我在Django Doc找到的。

quhf5bfb

quhf5bfb8#

我有个建议

class Car:
      name = models.CharField()
      launched_date = models.DateTimeField()

很难按今天日期过滤日期时间字段。即使你使用timezone.now()-你也不会得到正确的输出。因为timezone.now()也有时间。
日期时间字段有时间,所以即使你给出了正确的日期,时间也不会匹配。
所以
最好使用datefield进行基于日期的筛选

class Car:
      name = models.CharField()
      launched_date = models.DateField()

问题的答复:

from django.utils.timezone import datetime 
    today = datetime.today()
    events_for_today = Event.objects.filter(start_date__year=today.year,
                        start_date__month=today.month,
                         start_date__day=today.day)
3zwjbxry

3zwjbxry9#

因为它是一个DateTimeField使用start_date__date并执行OR (|)查询

from django.db.models import Q
from django.utils import timezone

today = timezone.now().date()
qs = Event.objects.filter(
    Q(start_date__date=today) |
    Q(end_date__date=today)
)

相关问题