首页 > 解决方案 > Django 高级 LIKE 过滤

问题描述

因此,我试图找到一种使用 Django 中的 LIKE 语句执行高级过滤器的好方法。

假设我在一个名为的表中有以下记录elements

id = 1, name = 'group[1].car[8]'
id = 2, name = 'group[1].car[9]'
id = 3, name = 'group[1].truck[1]'
id = 4, name = 'group[1].car[10]'
id = 4, name = 'group[1].carVendor[1]'

我想选择所有看起来像 group[x].car[y] 的元素。

要在 SQL 中查询这个,我会这样做:

SELECT * FROM elements WHERE name LIKE 'group[%].car[%]'

现在,通过阅读此处的 Django 文档,我看到唯一预先构建的 LIKE 语句如下:

  1. 包含:name LIKE '%something%'
  2. 以。。开始:name LIKE 'something%'
  3. 以。。结束:name LIKE '%something'

所以我需要的那个不见了:

  1. 简单的喜欢:name LIKE 'group[%].car[%]'

我还在使用 Django Rest Framework 来编写我的 API 端点,并且在这里我们发现了使用的可能性:

  1. 包含:name__contains = something
  2. 以。。开始:name__startswith = something
  3. 以。。结束:name__endswith = something

所以在这里,我需要的也不见了:

  1. 简单的喜欢:name__like 'group[%].car[%]'

当然我知道我可以使用该raw()方法通过 Django 编写原始 sql 查询,但是如果没有更好的解决方案出现,我想使用此选项,因为:

  1. 我需要确保我的定制是安全的
  2. 我需要将自定义扩展到 DRF

任何人都可以想出一种方法来帮助我解决这个问题,同时使用 Django 和 Django Rest Framework?

标签: djangodjango-rest-frameworksql-like

解决方案


您可以为此使用正则表达式 (regex) [wiki],并使用__iregex查找 [Django-doc]

Elements.objects.filter(name__iregex=r'^group\[.*\].car\[.*\]$')

如果方括号之间只允许使用数字,我们可以通过以下方式使其更具体:

# only digits between the square brackets
Elements.objects.filter(name__iregex=r'^group\[\d*\].car\[\d*\]$')

由于某些规范有点“复杂”,因此最好先测试您的正则表达式,例如使用regex101您可以查看哪些names 将匹配,哪些不匹配。


推荐阅读