我有一个卡片数据库,其中有一个Number
字段,它代表该集合中卡片的编号。该字段是一个 CharField
,因为某些卡片的编号后跟一个符号来表示同一卡片的不同版本。我想使用这个字段来排序我的数据,但是由于该字段是一个字符串,所以它的顺序很奇怪。例如; 1、10、100、101、102...
代码:
def cards_page(request):
card_list = Card.objects.exclude(side='b').extra(select={'int': 'CAST(number AS INTEGER)'}).order_by('int')
由于该字段中的符号,上面的代码失败了。我读到使用下面的正则表达式代码片段将删除非数字字符,但似乎无法让它在选择中工作。
"REGEXP_REPLACE(number, '[^0-9.]', '')"
有没有办法在转换为整数并按该值排序之前删除非数字字符?
最佳答案
您可以使用regexp_match
postgres function提取列中的第一组数字,然后将其转换
为整数。
这可能比使用 regexp_replace
函数更好,因为您只需要第一个连续的数字字符串,而不是连接的所有数字。
SQL_EXPRESSION = """
CAST(
(REGEXP_MATCH(number, '\d+'))[1] as INTEGER
)
"""
cards = Card.objects.exclude(side='b').extra(
select={'number_value': SQL_EXPRESSION}
).order_by('number_value')
注意:如果您使用的是 v10 之前的 PostgreSQL 版本,则需要使用类似 CAST((SELECT REGEXP_MATCHES(number, '\d+') )作为整数)
。这是described in the docs位于绿色“提示”框内。
在 django 中,上面的查询更具可重用性,并且更好地编写为 queryset function :
# This is just an example, I haven't tested it
from django.db.models import F, Func, IntegerField
class ExtractInteger(Func):
""" Returns the first int value from the string. Note that this
requires the string to have an integer value inside.
"""
function = 'REGEXP_MATCH'
template = "CAST( (%(function)s(%(expression)s, '\d+'))[1] as INTEGER )"
output_field = IntegerField()
cards = Card.objects.annotate(
number_value=ExtractInteger(F('name'))
).order_by('number_value')
关于python - Django Modals,从列中删除非数字字符,CAST 作为整数,然后排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65906634/