2

I've simplified the models for the question, but essentially I'm trying to perform a query with the following models:

class mod1(models.Model):
    mod1_id = CharField(unique=True, ...)

class mod2(models.Model):
    field2 = models.ManyToManyField(mod1)

So any mod2 object can have x number of mod1s...in this case I have a mod2 object that has four mod1 objects attached to it with the mod1_ids of "foo", "bar", "fizz", and "bang". If I have two different lists of mod1_ids, can I make separate Q objects of the lists to perform the filter so it returns my mod2 object? I've tried it and so far it hasn't yielded anything. Assume I can't combine the lists of ids to form one list. What I've tried:

from django.db.models import Q

Q1 = Q(field2__mod1_id__in=["foo"])
Q2 = Q(field2__mod1_id__in=["bar", "fizz"]

len(mod2.objects.filter(Q1 & Q2))
>>> 0

When I perform those queries individually, they both work, but together they don't. Can someone please help me out here? Thank you.

Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
Wolf
  • 63
  • 5
  • This question is answered in a [similar question](https://stackoverflow.com/questions/55400746/django-q-queries-on-the-same-field). The biggest difference is only the contains condition `Q(...__in=[...])` instead of equality `Q(...=...)`. – hynekcer Apr 04 '19 at 13:04

2 Answers2

1

You query make:

field2__mod1_id__in=["foo"] AND field2__mod1_id__in=["bar", "fizz"]

but You need:

field2__mod1_id__in=["foo"] OR field2__mod1_id__in=["bar", "fizz"]

if yes, use:

mod2.objects.filter(Q1 | Q2)

https://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects

EDIT:

Sets ["foo"] and ["bar", "fizz"] are exclusive. Don't have common part. The AND operator always return [].

Solution:

Query You need:

field2__mod1_id__in=["foo", "bar", "fizz"]

Python:

mod1sets = ["foo"]
mod1sets.append("bar")
mod1sets.append("fizz")

len(mod2.objects.filter(field2__mod1_id__in=mod1sets))
Community
  • 1
  • 1
Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
  • Thank, this make sense but still not what I want. I want to query to see if it has both of them only, not one or the other. – Wolf Jan 28 '16 at 13:14
  • Excuse a late comment. The question was for a queryset like for families that have one boy and one girl or more sons and daughters. It was a correct question even that a child boy and girl are exclusive. :-) I wrote an answer in [another question](https://stackoverflow.com/questions/55400746/django-q-queries-on-the-same-field) because this type conditions generate a multiple join with huge searched Cartesian product set, if the condition is not separated to a subquery. – hynekcer Apr 04 '19 at 13:21
0

Your query will genearte new Q object which satisfies

field2__mod1_id__in=["foo"] AND field2__mod1_id__in=["bar", "fizz"]

Your mod2 object is having only one object that does not satisfy this condition.

Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
praveen
  • 105
  • 2
  • 8