-1

Suppose I have query:

ExampleModel.objects.filter(some_datetime_field__gte=start, some_datetime_field__lte=end)

How do I get the list of all months present within "start" and "end" in the above mentioned query.

For example:

IF

start= 1/10/2018 and end=10/1/2019

Then the output will be:

OCTOBER
NOVEMBER
DECEMBER
JANUARY

Anyone any idea how to perform this?

Thank you in advance

Niladry Kar
  • 1,163
  • 4
  • 20
  • 50
  • See https://stackoverflow.com/questions/34898525/generate-list-of-months-between-interval-in-python/34899127 – art Jan 10 '19 at 11:30

2 Answers2

2

You can extract months and then get their names

from django.db.models.functions import ExtractMonth

months = (
    ExampleModel.objects
    .filter(some_datetime_field__gte=start, some_datetime_field__lte=end)
    .annotate(month=ExtractMonth('some_datetime_field'))
    .values_list('month', flat=True)
    .distinct()
)

At the end of this code you'll have a list of months(numbers). for example

[1, 3, 6, 8]

And you can get their names using calendar

import calendar

[calendar.month_name[month] for month in months]
Davit Tovmasyan
  • 3,238
  • 2
  • 20
  • 36
0

You can use annotation and Query Expressions.

import calendar

from django.db.models import Case, When, Value, CharField

conditions = []
for i in range(1, 13):
    month_name = calendar.month_name[i]
    conditions.append(When(some_datetime_field__month=i, then=Value(month_name)))

# conditions will be like below
# [
#     When(some_datetime_field__month=1, then=Value('January')),
#     When(some_datetime_field__month=2, then=Value('February')),
#     ...
# ]

ExampleModel.objects.annotate(
    month_name=Case(*conditions, default=Value(""), output_field=CharField())
).order_by("month_name").values_list("month_name", flat=True).distinct()

# Result will be like
# <ExampleModelQuerySet ['January', 'September']>
Rieljun Liguid
  • 1,511
  • 1
  • 10
  • 17