如何在Django ORM查询中筛选含指定值的ListTextField字段对象
如何在ORM中筛选ListTextField包含特定值的对象
没问题,这是个很常见的需求,我来帮你捋清楚怎么解决~
首先得说,你当前的代码逻辑偏了:Sample.objects.filter(x__in = sample_obj.x_list) 这种写法是用来判断某个字段的值是否在给定列表里,但你的需求是反过来的——要找x_list这个列表字段里包含特定值x的对象,所以得换个思路。
下面分两种常见的数据库后端场景给你具体方案,因为不同数据库对列表字段的存储实现不同,查询方式也略有区别:
场景1:用的是Django-Postgres的ArrayField(或兼容的ListTextField)
如果你的ListTextField是基于PostgreSQL的数组类型,Django已经给我们提供了现成的查询方式,用__contains查询,注意要把目标值放到一个列表里传进去:
x = 'abc' sample = Sample.objects.filter(x_list__contains=[x])
这个查询会自动转换成PostgreSQL的@>操作符,精准匹配所有x_list里包含x的对象。
场景2:用的是Django-MySQL的ListCharField/ListTextField
如果是MySQL环境下的列表字段,它本质是把列表存成逗号分隔的字符串(比如"abc,def,ghi"),这里有两种靠谱的查询方式:
x = 'abc' # 方法1:直接用__contains(适合x本身不含逗号的简单场景,Django-MySQL会自动处理分隔符) sample = Sample.objects.filter(x_list__contains=x) # 方法2:用正则匹配,避免部分匹配的问题(比如x='ab'不会误匹配到'abc') import re sample = Sample.objects.filter(x_list__regex=r'(^|,){0}(,|$)'.format(re.escape(x)))
第一种方法最简单,如果你能确定x里不会出现逗号,直接用就行;要是担心部分匹配的问题,第二种正则的方式更稳妥。
最后补个小提醒:你之前代码里的sample_obj(也就是取所有Sample对象)完全没必要,直接用上面的筛选语句就可以从数据库层面完成过滤,不用先把所有对象拉到内存里再处理,这样性能会好很多,尤其是数据量大的时候~
内容的提问来源于stack exchange,提问作者Abhijeet Khangarot
相关产品推荐
相关产品推荐

