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

Django中如何过滤genres数组包含指定ID的Film模型查询集?

如何过滤genres数组包含指定ID的电影

嘿,刚好我之前也处理过类似的需求,这得看你在Django里是用哪种字段来存储genres数组的,下面分两种常见情况来说:

情况1:使用PostgreSQL的ArrayField存储ID数组

如果你的Film模型里genres是用ArrayField(比如models.ArrayField(models.IntegerField()))定义的,那直接用__contains查询就能实现你要的效果——注意要把目标ID放到一个列表里传进去:

# 假设你要找包含genre_id=3的电影
target_genre_id = 3
result = Film.objects.filter(genres__contains=[target_genre_id])

这里要区分下__contains和__in的区别:

  • __in是判断字段值是否在给定的列表中(比如如果genres是单个ID的字段,那genres__in=[1,3]会找ID是1或3的电影)
  • 而针对ArrayField的__contains,是判断数组字段是否包含列表中的任意元素(这里传单个元素的列表,就是找数组里有这个ID的电影)

如果你的Django版本是3.2及以上,也可以用__overlap,效果和单元素的__contains一致:

result = Film.objects.filter(genres__overlap=[target_genre_id])

情况2:用其他字段存储(比如逗号分隔的字符串,不推荐)

如果你的genres是用普通CharField存的逗号分隔ID(比如"1,4,7"),这种方式其实不太推荐(查询效率低且容易出bug),但如果不得不这么做,可以通过添加前后逗号的方式避免误匹配(比如把1和11区分开):

from django.db.models import Value, CharField
from django.db.models.functions import Concat

target_genre_id = 3
# 给genres字段前后加上逗号,变成",1,4,7,",然后查询是否包含",3,"
result = Film.objects.annotate(
    formatted_genres=Concat(Value(','), 'genres', Value(','), output_field=CharField())
).filter(formatted_genres__contains=f',{target_genre_id},')

还是建议尽量换成ArrayField,不管是查询效率还是代码可读性都会好很多~

内容的提问来源于stack exchange,提问作者Vitali Skripka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:03:08