尝试使用Q对象过滤django查询集时出现逻辑错误

时间:2015-09-03 02:57:05

标签: python django django-queryset

我有一个具有单独的DateExpired和TimeExpired字段的模型:

class Thing(models.Model):
    name = models.CharField(max_length=50, unique=True)
    date_expired = models.DateField(blank=True, null=True)
    time_expired = models.TimeField(blank=True, null=True)

事情的到期时间如何:

  1. 如果date_expiredtime_expirednull:事情永不过期
  2. 如果date_expired exists,但time_expired为null:事件在日期过后
  3. 如果存在date_expiredtime_expired:事情将在该日期过期,
  4. 如果只有time_expired存在:事情在时间过后(每天,在时间= 00:00:00午夜时再次过期)
  5. 我想获得一个包含所有未过期的东西的查询集。目前,我可以使用以下代码成功捕获1,2和4:

    def not_expired(self):
        qs_ = self.filter( Q(date_expired = None) | Q(date_expired__gte = datetime.now) )
        return qs.exclude( Q(date_expired = None) & Q(time_expired__lt = datetime.now) )
    

    但我无法弄清楚如何添加要求#3。这就是我所拥有的:

    def not_expired(self):
        qs = self.filter( Q(date_expired = None) | Q(date_expired__gte = datetime.now) )
        qs = qs.exclude( Q(date_expired = datetime.now) & Q(time_expired__gt = datetime.now ))
        return qs.exclude( Q(date_expired = None) & Q(time_expired__lt = datetime.now) )
    

    但那里有一些错误,因为它没有解决#3。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,那些未过期的东西是:

  1. date_expired是>今天和time_expired是无
  2. date_expired是None和time_expired>现在
  3. date_expired>今天和time_expired>现在
  4. date_expired和time_expired都是无
  5. 如果是这样,我相信这会让你得到你想要的东西:

    now = datetime.datetime.now()
    
    qs.filter((Q(date_expired__gt=now.date()) & Q(time_expired = None)) |
              (Q(time_expired__gt=now) & Q(date_expired=None)) |
              (Q(date_expired__gt=now.date()) & Q(time_expired__gt=now)) |
              (Q(time_expired=None) & Q(date_expired=None)))
    

答案 1 :(得分:0)

试试这个,我认为这样可行;

now = datetime.datetime.now()

qs.filter( Q(date_expired__isnull=True, time_expired__isnull=True) | Q(date_expired__lte=now.date(), time_expired__isnull=True) | Q(date_expired__isnull=False, time_expired__isnull=False,date_expired__lte=now.date(), time_expired__lt=now.time()) |  Q(date_expired__isnull=True, time_expired__lt=now.time()))

#3解决方案

qs.filter(Q(date_expired__isnull=False, time_expired__isnull=False,date_expired__lte=now.date(), time_expired__lt=now.time()))