2015-09-03 43 views
0

我有了獨立的DateExpired和TimeExpired領域的典範:邏輯錯誤試圖篩選Django的查詢集爲Q對象

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 )

我想得到一個包含所有未過期事物的查詢集。目前,我可以成功捕捉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。

回答

0

如果我理解正確的話,那是沒有過期的東西是那些:

  1. 要麼date_expired是>今天time_expired是無
  2. 要麼date_expired是無與time_expired>現在
  3. 要麼date_expired >今天time_expired>現在
  4. 無論date_expired和time_expired是無

如果是這樣,我相信這應該得到你以後的東西:

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))) 
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()))