Python 多选字段中的一位数过滤

Python 多选字段中的一位数过滤,python,django,django-models,django-queryset,Python,Django,Django Models,Django Queryset,我有MyModel: class MyModel(models.Model): ELEMENTS_CHOICES = Choices( (1, 'element1'), (2, 'element2'), (3, 'element3'), (4, 'element4'), (10, 'element10'), (12, 'element12'), ) elements = Mul

我有
MyModel

class MyModel(models.Model):
    ELEMENTS_CHOICES = Choices(
        (1, 'element1'),
        (2, 'element2'),
        (3, 'element3'),
        (4, 'element4'),
        (10, 'element10'),
        (12, 'element12'),
    )
    elements = MultiSelectField(
        _('elements'),
        choices=ELEMENTS_CHOICES,
        blank=True,
    )
我还有一些
MyModel
对象,其
元素
值如下:

obj1.elements = ['1', '2', '3', '10', '12']
obj2.elements = ['1', '3', '10', '12']
obj3.elements = ['1', '3', '10']
obj4.elements = ['2']
如何筛选此字段值

我尝试使用的过滤器是:

search_id = 2
MyModel.objects.filter(elements_icontains=search_id)
MyModel
字段选项中出现两位数之前,一切正常。 现在,它返回
obj1
obj2
(因为
12
在列表中,它包含2个作为它的一部分)和
obj4

我只想搜索带有
2
number的值,并获得
obj1
obj4
作为结果。目前,结果是包含
2
12
的对象


过滤此字段的正确方法是什么?

在数据库中以逗号分隔的列表形式存储数据不是一种很好的技术,通常建议不要这样做。您的用例本身意味着您正面临这个问题。如果可行,您应该重新设计您的模型模式(推荐),并使用
外键
多域
来实现您的目标

如果由于某种原因无法更改此架构,则只能解析为使用正则表达式查询数据库:

import re


search_id = 2
filter_term = r'\b%s\b' % re.escape(str(search_id)) # \b is word boundary in regex
MyModel.objects.filter(elements__iregex=filter_term)

您应该为这个特定的问题建议适当的数据库规范化

如果您仍然发现自己必须在不更改数据库的情况下进行操作,您可以通过使用
string\u to\u array()

这将要求您在一行

WHERE 2 = any(string_to_array(elements));

然后,您可以添加以增加性能优势

您正在使用的数据库类型是什么,以及您为什么选择将其作为分隔列表存储在数据库中,当然在过滤性能@iklinac postgres 9.4方面存在许多缺点。数据库结构不是我的选择,我只是尝试在不更改数据库的情况下修复此筛选器。