Reputation: 4730
What I'm trying to do is annotate a queryset with the weekday strings ("monday", "tuesday"
etc).
I understand how to get the int values:
queryset = queryset.annotate(
weekday_int=ExtractWeekDay("date"),
)
But I'm having trouble getting the string values themselves. I've tried using an ExpressionWrapper
, but F
objects don't seem to play well with Date
objects.
I'm using postgres as my underlying database but can't find a related lookup_name
for the generic Extract
.
Upvotes: 3
Views: 529
Reputation: 509
When I tried the accepted answer on Django 4.2, there's a warning about ExtractWeekDay
has no convert_value
method.
A solution using Case
+ When
that parse weekday_int
onto week day name:
from django.db.models import Case, Value, When
from django.db.models.functions import ExtractIsoWeekDay
queryset = queryset.annotate(
# ISO-8601 week day with day 1 being Monday and day 7 being Sunday.
weekday_int=ExtractIsoWeekDay("date"), weekday_string=Case(
When(weekday_int=1, then=Value('Monday')),
When(weekday_int=2, then=Value('Tuesday')),
When(weekday_int=3, then=Value('Wednesday')),
When(weekday_int=4, then=Value('Thursday')),
When(weekday_int=5, then=Value('Friday')),
When(weekday_int=6, then=Value('Saturday')),
When(weekday_int=7, then=Value('Sunday')),
default=Value("")
)
)
Upvotes: 0
Reputation: 3294
I've tested this:
import calendar
class ExtractWeekDayName(ExtractWeekDay):
@property
def output_field(self):
return CharField()
def convert_value(self, value, expression, connection, context):
v = super(ExtractWeekDayName, self).convert_value(value, expression, connection)
try:
return calendar.day_name[int(v)].lower()
except (ValueError, IndexError):
return 'error'
except TypeError: # NoneType
return ''
Seems legit.
Upvotes: 2