包含匹配项的Django ArrayField过滤

时间:2019-12-13 10:50:01

标签: django django-models django-rest-framework django-forms django-templates

我正在使用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']

将返回obj1obj2,但

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

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

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

2 个答案:

答案 0 :(得分:2)

是的,只能进行精确的元素匹配。

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

将使用包含@>的postgresql执行精确匹配搜索。


但是,存在一个hacky选项,如果ArrayField仅包含简单字符串,则该选项很合适:

MyModel.objects.filter(response_headers__icontains='duba')

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

因此,它不是在检查数组中是否有任何元素(i),例如'duba',而是将数组转换为一个字符串(如果元素不是简单的字符串-结果可能是不可取的)-即{{1} },然后使用参数{dubai,sydney,nyc}执行不区分大小写的匹配。

答案 1 :(得分: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')