1

I have a three table model like that :

enter image description here

I want to filter results of a query with a variable list of items for exemple :

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

But the result of that query is all the ListTag objects with landscape OR green but what i want it's a list of ListTag objects with landscape AND green

I saw a lot a of answers about that problem but a lot of them use a static list of tags, what i want it's to filter with a variable listtags list

Edit : the model

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')
1
  • 1
    It's not clear what's the relationship between the models by looking at your graph, can you show the simplified model code for them please? Commented Dec 29, 2015 at 17:10

2 Answers 2

1

You can try to use Django Q object.

In your case this could be:

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()

addition:
if you want just pictures with tags, then you could use many-to-many relationships. But if you want use tags for different types of models, then u need to use generic relations.

In first case models structure could be:

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

With m2m relation Q object will not work, so to get all pictures with landscape and green tags you can use filter chaining:

listTags = ["landscape", "green"]

results = models.Picture.objects.all()
for tag in listTags:
    results = results.filter(tags__name = tag)
Sign up to request clarification or add additional context in comments.

2 Comments

it works as it should actually, it gets ListTag objects wich related to Tag objects with names landscape AND green. But it is impossible to obtain ListTag objects with landscape AND green with this models structure, its always will be only one Tag object landscape OR green related to TagList. Thats why results for this code is empty. I think you need to restucture your models and clarify your aim
Can you give me a way to change my model please ? My aim is to get pictures with some tags that the user can enter
0

I believe the code below would make this an AND query rather than an OR query:

listTags = ["landscape","green"]

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.