排除具有相关日期范围的对象

问题描述 投票:0回答:1

使用这些(当然是简化的)模型:

class Person(models.Model):
    name = models.CharField()

class InactivePeriod(models.Model)
    person = models.ForeignKeyField(Person)
    start_date = models.DateField()
    end_date = models.DateField()

class Template(models.Model):
    day = models.CharField() #choices = monday, tuesday, etc...
    person = models.ForeignKeyField(Person)

class TheList(models.Model):
    person = models.ForeignKeyField(Person)
    date = models.DateField(default=datetime.today)
    attended = models.BooleanField(default=False)

我有一个工作流程,人们打电话来报名参加每日活动(不会有在线注册)。最初,我的用户每天都会在呼叫时通过创建

TheList
记录手动输入每个与会者,然后检查他们是否出席。然而,由于每个活动都有通常在同一天出现的常客。我决定提供一个
Template
表,用户可以在其中指定“Mike”是“星期一”的常客,然后我将使用 cronjob 自动填充
TheList
表,其中包含以下人员的记录:那天的常客。然后,我的用户界面将自动过滤
TheList
列表视图,直至当天的与会者,然后我的用户可以根据需要进行任何更改。它只是减少了他们需要做的输入量。

问题是我的用户要求他们能够将某人指定为在一段时间内不活动。如果

Person
有相关的
InactivePeriod
记录,其中“今天”位于该记录的
start_date
end_date
之间,我的 cronjob 将忽略该
Person
。我决定不使用简单的“活跃”
BooleanField
,因为我认为他们更容易不必记住某人是否不活跃,并且不必担心将某人标记为不活跃的信息传达给其他用户。

我的脚本本质上是:

def handle(self, *args, **options):
    today = datetime.today()
    day = str(today.weekday()) #we store this as a string as it is a charfield

    is_inactive_today = (Q(person__inactiveperiod__start_date__lte=today) & \ 
                         Q(person__inactiveperiod__end_date__gte=today))

    attendance_list = []
    for t in models.Template.objects.filter(day=day).exclude(is_inactive_today):
        attendance_list.append(models.TheList(person=t.person, date=today))
    models.TheList.objects.bulk_create(attendance_list)

假设“今天”是 10/11/2024(2024 年 10 月 11 日),如果我为

InactivePeriod
添加两个
Person
,其中日期范围为(10/9/2024、10/10/2024)并且(10/12/2024, 10/13/2024),查询错误地没有返回
Person
的相关
Template
记录,尽管它们的
InactivePeriod
都不包含今天,并且作为这样我就无法创建合适的
TheList
记录。如果我删除任一记录,只留下一个
InactivePeriod
记录,则查询会成功返回相关的
Template
记录。

使用 ORM 可以做到这一点吗?还是我已经在 for 循环中写入了一些逻辑?

python django postgresql cron
1个回答
0
投票

Django DB 存储日期时间,包括时区信息。

由此产生的问题是预料之中的。 尝试使用 Django 的内置时区,而不是日期时间。

看来您的模型和视图需要修改。

from django.utils import timezone

now = timzone.now()
© www.soinside.com 2019 - 2024. All rights reserved.