在django中使用变量列表过滤查询

时间:2015-12-29 15:43:56

标签: sql django django-models django-views django-rest-framework

我有一个三表模型:

enter image description here

我想用例如项目的变量列表来过滤查询结果:

listTags = ["landscape","green"]
results = ListTag.objects.filter(tag__name__in=listTags).select_related()

但该查询的结果是所有带有风景 绿色的ListTag对象,但我想要的是'列表带有风景的ListTag对象 AND 绿色

我看到很多关于这个问题的答案,但很多人都使用静态的标签列表,我希望它能用变量列表标签列表进行过滤

编辑:模型

class Picture(models.Model):
    title = models.CharField(max_length=50,null=True, blank=False, verbose_name=('name'))

    def __str__(self):
        return self.titre

class Tag(models.Model):
    name = models.CharField(max_length=50,null=True, blank=False, verbose_name=('name'))

    def __str__(self):
        return self.name

class ListTags(models.Model):
    picture = models.ForeignKey(Picture, blank=False, on_delete=models.CASCADE, related_name='picture')
    tag = models.ForeignKey(Tag, blank=False, on_delete=models.CASCADE, related_name='tag')

2 个答案:

答案 0 :(得分:1)

您可以尝试使用Django Q object

在你的情况下,这可能是:

from django.db.models import Q

...

listTags = ["landscape","green"]

query = Q()
for tag in listTags:
    query &= Q(tag__name = tag)

results = ListTag.objects.filter(query).select_related()

<强>除了
如果您只想要带有标签的图片,那么您可以使用many-to-many relationships。但是如果你想为不同类型的模型使用标签,那么你需要使用generic relations

在第一种情况下,模型结构可能是:

from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=50, null=True, blank=False, verbose_name=('name'))

    def __str__(self):
        return self.name

class Picture(models.Model):
    title = models.CharField(max_length=50, null=True, blank=False, verbose_name=('name'))
    tags = models.ManyToManyField(Tag)

    def __str__(self):
        return self.title

使用m2m关系Q对象将无法正常工作,因此要使用横向和绿色标签获取所有图片,您可以使用过滤器链接:

listTags = ["landscape", "green"]

results = models.Picture.objects.all()
for tag in listTags:
    results = results.filter(tags__name = tag)

答案 1 :(得分:0)

我相信下面的代码会使这成为一个AND查询而不是OR查询:

listTags = ["landscape","green"]

filters = {}
for value in listTags:
    filters['tag__name__in'] = value

results = ListTag.objects.filter(**filters)