【问题标题】:Django ArrayField Filtering with contains matching包含匹配的 Django ArrayField 过滤
【发布时间】:2020-04-06 19:33:15
【问题描述】:

我正在使用 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 的所有索引中使用部分模式进行搜索?

【问题讨论】:

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


    【解决方案1】:

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

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

    将使用 postgresql contains @> 运算符执行完全匹配搜索。


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

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

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

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

    【讨论】:

      【解决方案2】:

      据我所知,您不能这样做,您可以使用 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')
      

      【讨论】:

        猜你喜欢
        • 2016-08-13
        • 1970-01-01
        • 2019-08-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-18
        • 2017-10-26
        • 2020-07-17
        • 1970-01-01
        相关资源
        最近更新 更多