如何在ArrayField(models.DateTimeField())字段中泛化两个日期以上的查询?



我有一个模型:

from django.contrib.postgres.fields import ArrayField
class MyClass(models.Model):
some_field = ArrayField(models.DateTimeField(), default=list)

并使用以下查询来筛选在一个范围内至少有一个日期的对象:

date_range_for_reminders_check = [yesterday.date(), timezone.now().date()]
MyClass.objects.filter((
Q(some_field__0__date__range=date_range_for_reminders_check) |
Q(some_field__1__date__range=date_range_for_reminders_check)
))

但是当MyClass的每一行在some_field中只有两个日期时,这是有效的,现在这些可能有更多的日期,需要普遍化,考虑到不同数量的日期,所以我需要这样的东西:

date_range_for_reminders_check = [two_days_ago.date(), timezone.now().date()]
MyClass.objects.filter((
Q(some_field__0__date__range=date_range_for_reminders_check) |
Q(some_field__1__date__range=date_range_for_reminders_check) |
Q(some_field__2__date__range=date_range_for_reminders_check) |
...
Q(some_field__X__date__range=date_range_for_reminders_check) |
))

但不指定索引

在关系数据库中使用数组字段通常是问题的根源。只有在非常特殊的情况下才能使用。

您通常使用额外的模型来保存单个时间戳和对所使用的MyClass的引用,因此:

class MyClass(models.Model):
pass

classMyClassTimestamp(models.Model):
myclass= models.ForeignKey(MyClass, on_delete=models.CASCADE)
timestamp = models.DateTimeField()

然后使用:

进行过滤
date_range_for_reminders_check = [yesterday.date(), timezone.now().date()]
MyClass.objects.filter(
myclasstimestamp__timestamp__in=date_range_for_reminders_check
).distinct()

最新更新