带有列表的Django过滤器过滤器

Rus*_*ine 6 python django django-queryset

所以,我有这个模型:

class Product(models.Model):
    colors = models.TextField(max_length=150,default = 'blue,green,blue')
Run Code Online (Sandbox Code Playgroud)

例如,我想用颜色列表过滤它。
关于我该怎么做的任何想法?
colors = ["blue","green"]
我需要这样的东西。

products = Product.objects.filter(colors__icontains = colors)
Run Code Online (Sandbox Code Playgroud)

关于如何修改模型以进行过滤的任何类型的帮助或建议都将受到赞赏。

Eli*_*iot 5

由于您将颜色存储为纯文本并且不使用相关模型,因此您无法使用所需的过滤器类型。

正确的方法是使用 a ManyToManyField:一种颜色可以有多种产品,一种产品可以有多种颜色:

class Color(models.Model):
    name = models.CharField(max_length=255)

class Product(models.Model):
    colors = models.ManyToManyField(Color, related_name='colors')
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样添加颜色:

blue = Color(name='blue')
blue.save()
red = Color(name='red')
red.save()
my_product = Product()
my_product.save()
my_product.colors.add(blue)
Run Code Online (Sandbox Code Playgroud)

如果您想查询所有红色或蓝色的产品,只需执行以下操作:

Product.objects.filter(colors__in=[red, blue]) # Red and blue being Color instances
Run Code Online (Sandbox Code Playgroud)

如果您想要所有红色和蓝色的产品,只需按照此处所述操作即可:

Product.objects.filter(colors=red).filter(colors=blue) # Red and blue being Color instances
Run Code Online (Sandbox Code Playgroud)

像这样的链接过滤器并不是特别方便,因此您可能需要一个QuerySet可以为您完成此操作的自定义过滤器:

class AllManyToManyQuerySet(models.QuerySet):
    def filter_all_many_to_many(self, attribute, *args):
        qs = self
        for arg in args:
            qs = qs.filter(**{attribute: arg})
        return qs

class Product(models.Model):
    colors = models.ManyToManyField(Color, related_name='colors')
    objects = AllManyToManyQuerySet.as_manager()
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

Product.objects.all().filter_all_many_to_many('colors', red, blue) # red and blue being color instances
Run Code Online (Sandbox Code Playgroud)

另一种过滤方法是:

product_list = Product.objects.filter(reduce(operator.and_, [Q(colors__name=c) for c in colors]))
Run Code Online (Sandbox Code Playgroud)

它未经测试,但应该可以工作,并且如果您在其他地方需要它,您可以在其他类上使用查询集,从而使代码保持干净和干燥;)