【问题标题】:Django Queryset: Cast VARCHAR field in SQL before filteringDjango Queryset:过滤前在 SQL 中转换 VARCHAR 字段
【发布时间】:2015-11-11 04:27:28
【问题描述】:

我有一个无法控制的表格,但需要从中进行选择。 “building”字段是一个 varchar,在我的(非托管)django 模型中也是这样定义的。但在从该表中选择时,应将其视为整数(有“000100”之类的值,甚至末尾有空格)。

我需要一个像这样的简单过滤器:

.annotate(CastInt("building")).filter(building__castint__exact=my_id)

唯一的问题是,CastInt 不存在。一个人怎么能做到这一点?我正在查看 .extra()(我们不应该再使用它,因为它已被弃用)和 RawSQL,但希望有一个仅使用 Django ORM 的解决方案,而不需要自定义编写的 SQL?

编辑:当前使用来自 here 的 hack(在 cmets 中):

Address.objects.extra(where=('CAST(TRIM(building) AS UNSIGNED)=%s',),
                      params=(building_no, ))

有效,但丑陋。

编辑二:查看我接受的答案 - 使用我的第二个最好的朋友,正则表达式。

【问题讨论】:

  • 转换为 int 的任何具体原因??
  • 如果“my_id”为100,则不会选择“000100”的行
  • 如果没有“工作”,则不需要强制转换。我看到了使用 __contains 的其他问题,但这不起作用,因为一行可能有“100100”作为构建字段值。
  • 只要写int(带前缀0的字符串)就可以自动转换成实数
  • 我认为它丑陋或骇人听闻。 extra 的目的,根据 django 文档是添加 a hook for injecting specific clauses into the SQL generated by a QuerySet.,总有一些情况 orm 没有覆盖足够的。但请注意,如果您更改数据库后端,原始查询可能无法正常工作。

标签: python django django-models django-orm


【解决方案1】:

尽可能简单:使用正则表达式查询

regex = r'^0{0,4}%s ?$' % building_no
address = Address.objects.filter(building__iregex=regex)\

欢迎任何有关性能的提示...

【讨论】:

    【解决方案2】:

    尝试简单的int(you string value)

    例如:

    str = "00100"
    int(str)
    

    将给出 100 作为整数值。 同样适用于

     str = "100100"
    int(str)
    

    以整数形式给出 100100

    【讨论】:

    • 我已经有一个真正的 int (如你所建议的那样被强制转换),它需要过滤我的 django 查询集。问题是数据库中的值:它是“000100”,如果我只是做一个 Address.objects.filter(building=myfiltervalue),它不会按我想要的方式过滤(0 个结果)
    • myfiltervalue的值是什么?
    • 我认为@benzkji 询问的是如何创建正确的查询,而不是如何在intstr 之间进行转换。
    • 是的。我还在寻找解决方案。。@ShangWang:你有什么想法吗?
    猜你喜欢
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 2020-02-06
    • 2021-09-18
    • 2014-07-13
    • 2010-09-23
    相关资源
    最近更新 更多