0

I have confusing problem in querying in django. I know its not a bug and it is something that I don't know.

So models are:

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

class AttributeValue(models.Model):
    value = models.CharField(max_length=255)
    product = models.ForeignKey(Product, related_name='attribute_values', on_delete=models.CASCADE)

I have one product object called T-shirt and it has two AttributeValue with ids 1, 2. And when I filter like this (1):

Product.objects.filter(Q(attribute_values__pk__in=[1, 2]))

Its returning my T-shirt object. But when I filter like this (2)

Product.objects.filter(Q(attribute_values__pk__in=[1]) & Q(attribute_values__pk__in=[2]))

there is no queryset found here. How is this happening? Previous codes are just examples and I have project that really need to do with this second filter (2).

2 Answers 2

4

This will never return any query results:

Product.objects.filter(Q(attribute_values__pk__in=[1]) & Q(attribute_values__pk__in=[2]))

# Equivalent to:
Product.objects.filter(attribute_values__pk=1).filter(attribute_values__pk=2)

Why? Because there is no object that simultaneously possesses both a primary key of 1 AND a primary key of 2.

You want the Q objects to be "OR"ed together instead of "AND"ed, so this is what you actually want:

Product.objects.filter(Q(attribute_values__pk__in=[1]) | Q(attribute_values__pk__in=[2]))

But why use Q objects when you can achieve the same without them? For instance:

Product.objects.filter(attribute_values__pk__in=[1, 2])
Sign up to request clarification or add additional context in comments.

2 Comments

But I want "AND"ed in my current project case
@kyore I think I now understand what you want. See if this question helps: stackoverflow.com/questions/48238999/…
0

In this

Product.objects.filter(Q(attribute_values__pk__in=[1]), Q(attribute_values__pk__in=[2]))

your are using Q expression with and which will not setisfy what you want so for expected output either:

Product.objects.filter(Q(attribute_values__pk__in=[1, 2]))

or

Product.objects.filter(Q(attribute_values__pk__in=[1]) | Q(attribute_values__pk__in=[2]))

but you should use the first one without Q expression

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.