Search code examples
djangodjango-orm

How to annotate a Django queryset with a boolean value for "is older than n days"?


Given the toy example of a model:

class Article(models.Model):
    title = models.CharField(max_length=64)
    published = models.DateTimeField()

How might you get a queryset such that you can tell whether the article was published over 2 years ago?

I was thinking something like this, but it didn't pan out:

Article.objects.all().annotate(
    is_relevant=ExpressionWrapper(
        timezone.now() - F("start") > timedelta(days=365 * 2),
        output_field=BooleanField(),
    )
)

Basically, I want to be able to iterate over the list of articles and access article.is_relevant in the template to decide how I might render it.


Solution

  • Just work with it the opposite way:

    from django.db.models import ExpressionWrapper Q
    from django.db.models.functions import Now
    
    Article.objects.annotate(
        is_relevant=ExpressionWrapper(
            Q(published__gte=Now() - timedelta(days=2 * 365)),
            output_field=BooleanField(),
        )
    )

    We thus check if it is published after two years ago.