2016-11-15 77 views
3

我需要過濾比X更早的天數。我意識到這個問題存在的位置:django filter older than day(s)?Django - 過濾超過X天的對象

但是,我並不想做到這些,因爲天數,在我的情況下,生活在模型內部:

class Post(models.Model): 
    title = models.CharField(max_length=200) 
    description = models.CharField(max_length=500) 
    createdAt = models.DateTimeField(default=datetime.now, blank=True) 
    plan = models.ForeignKey(Plan) # This model has the number of days 

這是查詢我有這麼遠:

編輯:我改變了days.plan一部分the_post.plan.days意思是,我使用比較的天數在每個崗位的​​場。

Post.objects.filter(createdAt__lte=datetime.now() - timedelta(days=the_post.plan.days)) 

請注意plan.days部分查詢。如何爲此查詢參考the_post.plan.days?可能嗎?

回答

2

隨着你的計劃模型中的小調整,這的確是可能做到你想做的。

首先,您需要將您的計劃days字段(可能是IntegerField)更改爲DurationField

現在,我們必須使用ExpressionWrapper來實現Postgres中完全相同的結果,因爲如果要在單獨的查詢中獲得計劃,那麼您將在Python中實現該結果。

最後,您的查詢應該是這樣的:

from django.db.models import F, ExpressionWrapper, DateTimeField 
from django.utils import timezone 

Post.objects.annotate(target_date=ExpressionWrapper(timezone.now() - F('plan__days'), output_field=DateTimeField())).filter(createdAt__lte=F('target_date')) 
+0

嗨@lucasnadalutti這似乎是正確的答案,但是,我得到這個錯誤:'ValueError:不天真的日期時間(tzinfo已設置)'不知道爲什麼 – danielrvt

+0

嘗試用'時區'替換'datetime.now()' .now()',它是從'django.utils import timezone'輸入的 – lucasnadalutti

0

對我來說,你必須先抓住計劃對象。

plan = Plan.objects.filter(...) 

然後引用天

Post.objects.filter(createdAt__lte=datetime.now() - timedelta(days=plan.days)) 
+0

這是如何從什麼的問題中包含有什麼不同? – Brian

+0

Post模型中的計劃引用了另一個表,因此無法知道日子是什麼。 在這個例子中,我首先得到了我需要的計劃,而在計劃變量中是天變量(例如3)。然後你可以找到你需要的給定計劃的帖子。 – user2693928

+0

這已經是問題所在了; 'plan.days'會另外讀取'Post.plan.days'(這是一個AttributeError)或類似的。 – Brian

1

假設Postgres數據庫:

table_post = Post._meta.db_table 
table_plan = Plan._meta.db_table 

old_posts = Post.objects.select_related('plan')\ 
      .extra(where=["%s.created_at <= NOW() - INTERVAL '1 day' * %s.days" 
          % (table_post, table_plan)])