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)
在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,因此您需要确保该子句对您的数据库有效.
希望这对你有用.
有点拗口,但您可以通过注释搜索值然后对其进行过滤来做到这一点。一切都在数据库中很快发生。
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.
我相信现在你也可以通过一个很好的模板函数来做到这一点......但这对我来说已经足够干净了。