【问题标题】:Django - Filter objects older than X daysDjango - 过滤超过 X 天的对象
【发布时间】:2016-11-15 18:37:46
【问题描述】:

我需要过滤早于X 天数的对象。我意识到这里存在这个问题:django filter older than day(s)?

但是,我并没有尝试这样做,因为在我的情况下,天数存在于模型中:

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,这意味着我用来比较的天数在每个帖子的 plan 字段中。

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

注意查询的plan.days 部分。我如何为这个查询引用the_post.plan.days?有可能吗?

【问题讨论】:

    标签: python django


    【解决方案1】:

    在您的计划模型中稍作调整,确实可以做您想做的事情。

    首先,您需要将您的计划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'))
    

    【讨论】:

    • 嘿@lucasnadalutti 这似乎是正确的答案,但是,我又收到了这个错误:ValueError: Not naive datetime (tzinfo is already set) 不知道为什么
    • 尝试将datetime.now()替换为timezone.now(),将其导入为from django.utils import timezone
    【解决方案2】:

    假设 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)])
    

    【讨论】:

      【解决方案3】:

      对我来说,你必须先抓住计划对象。

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

      然后参考天数

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

      【讨论】:

      • 这与问题包含的内容有何不同?
      • Post 模型中的计划是对另一个表的引用,所以它不知道是什么日子。在示例中,我首先得到了我需要的计划,而在计划变量中是天变量(例如 3)。然后你可以找到你需要的给定计划的帖子。
      • 这已经是问题在做什么了; plan.days 否则会读取 Post.plan.days(这是一个 AttributeError)或类似的。
      • 难道我不必在单独的查询中获取计划对象吗?我的意思是,它已经在帖子中了。
      • 如果您有播放对象,您的查询应该可以工作。计划对象是否包含整数形式的天数字段
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 2012-08-21
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      相关资源
      最近更新 更多