所以,我有这个模型:
class Product(models.Model):
colors = models.TextField(max_length=150,default = 'blue,green,blue')
例如,我想用颜色列表过滤它。
知道我该怎么做吗?
colors = ["blue","green"]
我需要这样的东西。
products = Product.objects.filter(colors__icontains = colors)
任何关于如何修改模型以进行过滤的帮助或建议都将不胜感激。
最佳答案
由于您将颜色存储为纯文本且未使用相关模型,因此您无法使用所需的滤镜类型。
正确的方法是使用 ManyToManyField
:一种颜色可以有多种产品,一种产品可以有多种颜色:
class Color(models.Model):
name = models.CharField(max_length=255)
class Product(models.Model):
colors = models.ManyToManyField(Color, related_name='colors')
然后,您可以像这样添加颜色:
blue = Color(name='blue')
blue.save()
red = Color(name='red')
red.save()
my_product = Product()
my_product.save()
my_product.colors.add(blue)
如果要查询所有红色或蓝色的产品,只需执行以下操作:
Product.objects.filter(colors__in=[red, blue]) # Red and blue being Color instances
如果您想要所有红色和蓝色的产品,请按说明操作 here :
Product.objects.filter(colors=red).filter(colors=blue) # Red and blue being Color instances
像这样链接过滤器并不是特别方便,因此您可能需要自定义 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()
然后像这样使用它:
Product.objects.all().filter_all_many_to_many('colors', red, blue) # red and blue being color instances
另一种过滤方法是:
product_list = Product.objects.filter(reduce(operator.and_, [Q(colors__name=c) for c in colors]))
它未经测试,但它应该可以工作,如果你在其他地方需要它,你可以在其他类上使用查询集,保持你的代码干净和干燥;)p>
关于python - 带列表的 Django 过滤器过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33781294/