2016-11-15 78 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)])