'its possible to get months between two dates in django queryset?

I'm trying to get make a complete query set, and now all I need is get the months between two DateTime fields from my model, it's possible to do this action in a single query set. Im not talking about filter, cause in the model for example I have two datetimeField() and now what I want to do is, gets months between this dates.



Solution 1:[1]

The given answer didn't work for me on postgres because the diff field (DurationField) only support to Extract days function. ExtractMonth return "0".

Here the solution I've found :

queryset = MyModel.objects.annotate(
    months=(ExtractYear("date2") - ExtractYear("date1")) * 12 + (ExtractMonth("date2") - ExtractMonth("date1"))
)

Note that it only consider the difference between the first of each month and not an eventual fractional part given by the days. In this solution 2020-08-12 is considered as the same as 2020-08-01.

Solution 2:[2]

Django v4.0.4   PostgreSQL v13.4

date2_date1_months_elapsed returns how many months (as an integer) have elapsed between two dates.

created_on_months_elapsed returns how many months (as an integer) have elapsed between today and a creation date.

from django.db.models import F, IntegerField
from django.db.models.functions import Cast, ExtractDay, TruncDate
from django.utils import timezone


class MyModel(models.Model):
    date1 = models.DateTimeField()
    date2 = models.DateTimeField()
    created_on = models.DateTimeField(default=timezone.now)
    ...


queryset = MyModel.objects.annotate(
    date2_date1_days_diff=Cast(
        ExtractDay(
            TruncDate(F("date2")) - TruncDate(F("date1"))
        ),
        IntegerField(),
    ),
    date2_date1_months_elapsed=Cast(
        F("date2_date1_days_diff") / (365 / 12), IntegerField()
    ),
    created_on_days_diff=Cast(
        ExtractDay(
            TruncDate(timezone.now()) - TruncDate(F("created_on"))
        ),
        IntegerField(),
    ),
    created_on_months_elapsed=Cast(
        F("created_on_days_diff") / (365 / 12), IntegerField()
    )
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 JV conseil