【问题标题】:Django QuerySet: filter by 'value LIKE column'Django QuerySet:按“值 LIKE 列”过滤
【发布时间】:2019-05-20 10:01:54
【问题描述】:

我有一个 SQL 查询来确定匹配给定输入字符串的最长匹配前缀。用例是找到调用给定目的地的速率,该速率由数据库中的多行确定。最具体的匹配前缀是要使用的。

所以在原始 SQL 中它看起来像这样:

SELECT * FROM rateplan_rates
WHERE '3212345789' LIKE CONCAT(prefix, '%')
ORDER BY CHAR_LENGTH(prefix) DESC LIMIT 1

在上面的示例中,目的地是 3212345789。在实际应用程序中,这是由缓存机制和更多东西支持的,但归根结底就是这样。

我想在我们的 Django 项目中为 API 调用完成相同的操作,并且我知道我也可以在那里使用原始 SQL,但我想知道是否有办法在 Django“queryset-language”中执行.

我被这个困住了:

RateplanRate.objects \
    .annotate(prefix_length=Length('prefix'), prefix_match=Concat('prefix', '%')) \
    .filter('search_value LIKE prefix_match') \
    .order_by('-prefix_length')[0:1]

当然,缺少的部分是search_value LIKE prefix_match。这是可能的还是我应该回退到原始 SQL?

【问题讨论】:

    标签: python django django-orm


    【解决方案1】:

    我认为您正在寻找类似 @​​987654321@ 或 contains 的东西

    例如

    RateplanRate.objects.filter(field__icontains='foobar')
    

    【讨论】:

    • 但是在这里你把它换过来,想法是prefix字段应该是值的前缀('foobar')。
    • 没错,我需要'foobar__icontains=field',你可以说。
    • 我不确定我是否理解正确,但请查看Query Expressions,这可能对您有用。
    • @HigorRossato:需要交换操作数,不是field LIKE value,而是value LIKE field
    • @WillemVanOnsem 我现在知道了。
    【解决方案2】:

    我们需要为这样的东西添加一个额外的()过滤器

    RateplanRate.objects.extra(select={'prefix_length':'prefix.length', }).extra(where=["%s LIKE concat(prefix,'%%')"], params=[search_value]).order_by('-prefix_length')
    

    【讨论】:

      猜你喜欢
      • 2017-10-12
      • 2020-01-01
      • 2018-06-24
      • 1970-01-01
      • 2014-07-13
      • 2018-01-05
      • 2013-09-08
      • 1970-01-01
      • 2018-01-21
      相关资源
      最近更新 更多