You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django views.py中过滤Product模型的categories数组字段并获取去重值

解决Django数组字段获取去重元素的问题

我明白你遇到的困扰了——用普通的values_list('categories', flat=True).distinct()没法拿到数组字段里单个元素的去重值,因为这个写法只会对整个数组做去重,而不是拆分数组内部的内容。下面给你两种靠谱的解决方案(默认你用的是PostgreSQL的ArrayField,这是Django里最常用的数组字段实现):

方法一:用Django内置的Unnest函数(Django 3.2+)

如果你的Django版本在3.2及以上,直接用官方提供的Unnest函数就能轻松拆分数组,再获取去重值:

from django.contrib.postgres.functions import Unnest

# 获取所有不重复的分类值
unique_categories = Product.objects.annotate(
    single_category=Unnest('categories')
).values_list('single_category', flat=True).distinct()

原理很直观:Unnest('categories')会把每个产品的categories数组拆分成单独的行,每行对应一个分类元素;然后我们通过annotate把这些元素命名为single_category,最后用values_list提取并去重。

方法二:自定义Unnest函数(适用于旧版Django)

如果你的Django版本低于3.2,自己定义一个简单的Func类就能实现同样的效果:

from django.db.models import Func

class Unnest(Func):
    function = 'UNNEST'
    arity = 1

# 执行查询获取去重分类
unique_categories = Product.objects.annotate(
    single_category=Unnest('categories')
).values_list('single_category', flat=True).distinct()

这里的UNNEST是PostgreSQL自带的函数,专门用来把数组拆分成行数据,我们用Django的Func把它包装成ORM能识别的操作。

为什么原来的写法不行?

你之前用的Product.objects.values_list('categories', flat=True).distinct(),返回的是每个产品的整个categories数组,distinct()只是把重复的数组(比如两个产品都有["电子产品", "手机"]这样的数组)去重,而不会拆分数组里的单个元素——这就是你拿不到想要结果的原因。

备选方案(仅适合小数据集)

如果因为某些限制没法用数据库层面的拆分,也可以在Python代码里处理,但这种方法在产品数据多的时候性能很差,只适合小量数据:

all_categories = []
# 遍历所有产品,把每个产品的分类加到列表里
for product in Product.objects.all():
    all_categories.extend(product.categories)
# 用集合去重再转成列表
unique_categories = list(set(all_categories))

内容的提问来源于stack exchange,提问作者Dhany P Sukumaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:12:12