首页 > 解决方案 > Django Queryset 按确切字符串过滤数组字段

问题描述

所以我和 Django 合作太久了。我遇到了一个问题,通过传递给它的数组字符串的确切名称过滤查询集。目前,我正在通过 icontains 过滤查询集,这很有效。例如,当前的实现是这样工作的:如果我传入一个名为“test”的字符串,我的查询集将被过滤并显示带有标签“test1”、“test2”和“test3”的交易。这不是我想要的。我想通过传入的字符串的确切名称进行过滤。因此,如果我有一个“测试”作为字符串之一,那么我的查询集将只搜索测试,而不是其中包含的任何内容。我尝试了多种实现,例如从 icontains 切换到 iexact 和精确。

目标。按多个标签的数组过滤查询集。

旧查询:值是传入的标签(字符串)数组

values = value.replace(" ", "").split(",")
return qs.filter(reduce(operator.or_, (Q(tags__iontains=item) for item in values)))

我尝试过的:我尝试使用如下值列表传入 iexact。我也试过只传递 iexact,然后从数组中只传递一个硬编码字符串。当我只用 iexact 传入一个字符串时,我遇到了一个错误,上面写着:“不支持 ArrayField 的查找或加入不允许的字段”这是有道理的,因为这是一个数组。

values = value.replace(" ", "").split(",")
return qs.filter(reduce(operator.or_, (Q(tags__iexact=item) for item in values)))

有没有人遇到过这个问题并知道解决方法?我一直在阅读文档和堆栈溢出,但找不到解决方案。

标签: arraysdjangostringfilterdjango-queryset

解决方案


假设这是特定于 PostgreSQL 的ArrayField- 这看起来像overlap查找。也就是说,假设您想要任何指定值的结果。如果contains您想要具有所有指定值的结果。

从文档:

overlap

Returns objects where the data shares any results with the values passed. Uses the SQL operator &&. For example:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])

>>> Post.objects.filter(tags__overlap=['thoughts']) <QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial']) <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>


>>> Post.objects.filter(tags__contains=['thoughts']) <QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__contains=['django']) <QuerySet [<Post: First post>, <Post: Third post>]>

>>> Post.objects.filter(tags__contains=['django', 'thoughts']) <QuerySet [<Post: First post>]>

推荐阅读