python - Django Modals,从列中删除非数字字符,CAST 作为整数,然后排序

标签 python python-3.x django postgresql

我有一个卡片数据库,其中有一个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/

相关文章:

Python链表删除方法不起作用

python - 如何在 python 中发出删除/放置请求

python - 在 CentOS for Python 上升级 Sqlite3 版本时出现问题

python - Django 1.7 迁移挂起

python - 如何为 PyInstaller 创建 Hook 模块?

python - 进程以退出代码 245 结束

python - 创建一个 python 单元测试,其中缺少模块是伪造的

python - 单独模块中的 Flask View

python - 如何设置路径以将数据从 CSV 文件加载到 Docker 容器中的 PostgreSQL 数据库中?

python - 在单个方法上启用 django 的 TEMPLATE_STRING_IF_INVALID