在我的Django Rest框架项目中,我有一个自定义的filter_backends,它允许按大小写不敏感地过滤:
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
这在开发中运行良好。
现在我在elastic beanstalk上托管了django应用程序,并通过amazon关系数据库服务(RDS)配置了一个postgresql数据库。
当我现在尝试调用API时,我得到这个错误:
ProgrammingError at/api/profile_list/function lower(bigint)没有exist LINE 1:…"; "author_id")组由"user_user";id"命令低(清纯甜美…
提示:没有函数匹配给定的名称和参数类型。你可能需要添加显式类型强制转换。
此错误仅在RDS部署中出现。
我尝试在django中使用:
field = str(field)
但这不起作用。是否有任何方法允许在没有较低函数的情况下进行不区分大小写的排序,或者我如何有条件地检查它是数字(并进行强制转换?)还是文本abd
你得到的错误,因为你使用Lower
的字段,这可能是一个IntegerField
或其他东西。在实际使用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
回答这个评论中的其他问题:
我想知道为什么这段代码与我的本地数据库一起工作。sqlite,但不支持RDS. ...
PostgreSQLlower
函数(在RDS上使用)只接受文本值
SQLitelower
函数也接受整数,尽管在文档中没有明确提到。
这可能与"SQLite使用更通用的动态类型系统"有关。
这说明了为什么在本地和生产中使用相同的RDBMS是有利的。
注意:
虽然当你做类似
这样的操作时SQLite不会报错... ORDER BY LOWER("my_integer_field")
结果可能会令人惊讶,因为它将按照字典顺序排列。
例如
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
将作为文本排序,产生
[1, 10, 11, 12, 2, 3, 4, 5, 6, 7, 8, 9]