Django从字段开始

sfa*_*riz 20 django startswith filter

假设我有一个带有邮政编码字段的地址模型.我可以使用此行查找以"123"开头的邮政编码的地址:

Address.objects.filter(postcode__startswith="123")
Run Code Online (Sandbox Code Playgroud)

现在,我需要搜索"其他方式".我有一个带有postcode_prefix字段的地址模型,我需要检索postcode_prefix是给定代码前缀的所有地址,如"12345".因此,如果在我的数据库中我有2个地址使用postcode_prefix ="123"和"234",则只返回第一个地址.

就像是:

Address.objects.filter("12345".startswith(postcode_prefix)) 
Run Code Online (Sandbox Code Playgroud)

问题是这不起作用.我能想出的唯一解决方案是对第一个char执行过滤,例如:

Address.objects.filter(postcode_prefix__startswith="12345"[0])
Run Code Online (Sandbox Code Playgroud)

然后,当我得到结果时,制作一个列表理解,正确过滤它们,如下所示:

results = [r for r in results if "12345".startswith(r.postcode_prefix)]
Run Code Online (Sandbox Code Playgroud)

在django有更好的方法吗?谢谢你,法布里奇奥

Joe*_*Day 21

我认为你正在尝试用你的"类似"线做的就是这样:

Address.objects.filter(postcode__startswith=postcode_prefix)
Run Code Online (Sandbox Code Playgroud)

  • 实际上,OP 想要反过来。 (3认同)

cyr*_*oxx 9

在SQL术语中,您想要实现的内容如('12345'是您要搜索的邮政编码):

SELECT *
FROM address
WHERE '12345' LIKE postcode_prefix||'%'
Run Code Online (Sandbox Code Playgroud)

这不是一个真正的标准查询,我没有看到任何可能只使用get()/ filter()在Django中实现这一点.

但是,Django提供了一种方法来提供额外的SQL子句extra():

postcode = '12345'
Address.objects.extra(where=["%s LIKE postcode_prefix||'%%'"], params=[postcode])
Run Code Online (Sandbox Code Playgroud)

有关extra()的详细信息,请参阅Django文档以获取进一步的参考.另请注意,extra包含纯SQL,因此您需要确保该子句对您的数据库有效.

希望这对你有用.


Oli*_*Oli 6

有点拗口,但您可以通过注释搜索值然后对其进行过滤来做到这一点。一切都在数据库中很快发生。

from django.db.models import Value as V, F, CharField

Address.objects.exclude(
    postcode_prefix=''
).annotate(
    postcode=Value('12345', output_field=CharField())
).filter(
    postcode__startswith=F('postcode_prefix')
)
Run Code Online (Sandbox Code Playgroud)

仅当可以为空时才是exclude必需的postcode_prefix。这将产生一个 SQL like '%',它将匹配每个postcode.

我相信现在你也可以通过一个很好的模板函数来做到这一点......但这对我来说已经足够干净了。