Django中的ArrayField过滤器:使用contains匹配

6
我正在使用Django Postgres ArrayField。
response_headers = ArrayField(models.TextField(blank=True),blank=True,null=True,default=list)

假设我们的对象具有以下数据:

obj1 : response_headers = ["dubai","sydney","nyc"]
obj2 : response_headers = ["mumbai","kerela","dubai"]

MyModel.objects.filter(response_headers__contains=['dubai']

将返回 obj1 & obj2 ,但是

MyModel.objects.filter(response_headers__contains=['duba']
   or 
MyModel.objects.filter(response_headers__contains=['uba']

不会返回任何对象 <QuerySet []>

我如何实现在ArrayField的所有索引中使用部分模式进行搜索的能力?

2个回答

8

是的,只有精确的元素匹配才是可能的。

MyModel.objects.filter(response_headers__contains=['duba'])


将使用PostgreSQL的@>运算符执行精确匹配搜索。
然而,如果ArrayField仅包含简单字符串,则存在一种Hacky选项,可能是合适的。
MyModel.objects.filter(response_headers__icontains='duba')

这将把ArrayField转换为文本,将其大写并执行LIKE '%DUBA%'

因此,它不是检查数组中是否有任何元素类似于'duba',而是将数组转换为一个字符串(如果元素不是简单的字符串,则结果可能不理想)-即{dubai,sydney,nyc},然后对其进行不区分大小写的匹配,与参数duba匹配。


1
据我所知,你无法这样做,你可以使用index transform在数组的特定项中搜索,但不能同时查看每个单独的项。建议为您的响应头创建一个新模型,并使用关系进行过滤,例如:
class Header(models.Model):
    value = models.CharField(max_length=255)

class Response(models.Model):
    ...
    headers = models.ManyToManyField(Header)


responses = Response.objects.filter(headers__value__contains='duba')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接