In my Django Rest Framework project, I have a custom filter_backends that allows filtering by case insensitively:
class CaseInsensitiveOrderingFilter(OrderingFilter):
def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if ordering:
new_ordering = []
for field in ordering:
# field = str(field)
print(Lower(field))
if field.startswith('-'):
new_ordering.append(Lower(field[1:]).desc())
else:
new_ordering.append(Lower(field).asc())
return queryset.order_by(*new_ordering)
return queryset
This works fine in development.
Now I hosted the django app on elastic beanstalk and I configured a postgresql database via amazon relational database service (RDS).
When I try now to call the API, I get this error:
ProgrammingError at /api/profile_list/ function lower(bigint) does not exist LINE 1: ..."."author_id") GROUP BY "user_user"."id" ORDER BY LOWER(COUN...
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
This error appears only in the RDS deployment.
I tried to type cast the fields in django with:
field = str(field)
But this is not working. Is there any way to allow caseinsensitive ordering without the lower function, or how can I conditionally check if it is a number (and cast then?) or a text abd
You get the error because you use Lower
on a field which is perhaps an IntegerField
or something else. You want to be checking what your field is before actually using Lower
:
from django.db import models
def get_field_type(field_name, queryset):
stripped_field_name = field_name.lstrip('-')
if stripped_field_name in queryset.query.annotations:
return queryset.query.annotations[stripped_field_name].output_field
return queryset.model._meta.get_field(stripped_field_name)
class CaseInsensitiveOrderingFilter(OrderingFilter):
def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if ordering:
new_ordering = []
for field in ordering:
if not isinstance(get_field_type(field, queryset), (models.CharField, models.TextField)):
# Most of the character type fields inherit from CharField.
# I might miss a few fields here so you would need to make sure
new_ordering.append(field)
elif field.startswith('-'):
new_ordering.append(Lower(field[1:]).desc())
else:
new_ordering.append(Lower(field).asc())
return queryset.order_by(*new_ordering)
return queryset