Django Queryset 按确切字符串过滤数组字段
Posted
技术标签:
【中文标题】Django Queryset 按确切字符串过滤数组字段【英文标题】:Django Queryset filter array field by exact string 【发布时间】:2021-09-18 11:22:40 【问题描述】:所以我已经很久没有使用 Django 了。我遇到了通过传递给它的数组字符串的确切名称过滤查询集的问题。目前,我正在通过 icontains 过滤查询集,这很有效。例如,当前的实现是这样工作的:如果我传入一个名为“test”的字符串,我的查询集将被过滤并显示带有标签“test1”、“test2”和“test3”的交易。这不是我想要的。我想通过传入的字符串的确切名称进行过滤。因此,如果我有一个“测试”作为字符串之一,那么我的查询集将只搜索测试,而不是其中包含的任何内容。我尝试了多种实现方式,例如从 icontains 切换到 iexact 和精确。
目标。按多个标签数组过滤查询集。
旧查询:values 是传入的标签(字符串)数组
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)))
有没有人遇到过这个问题并知道解决方法?我一直在阅读文档和堆栈溢出,但找不到解决方案。
【问题讨论】:
【参考方案1】:假设这是特定于 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>]>
【讨论】:
有了重叠,我怎样才能像在我的例子中那样使数组字符串动态化?tags__overlap=values
,和正常传入过滤参数一样。它需要一个序列,因此您需要按照所示拆分字符串。以上是关于Django Queryset 按确切字符串过滤数组字段的主要内容,如果未能解决你的问题,请参考以下文章
Django Admin:获取根据 GET 字符串过滤的 QuerySet,与更改列表中看到的完全一样?
在django中动态添加参数到queryset过滤器调用[重复]