Filter with multiple conditions on a single related object

10,830

Solution 1

Edit: What you are saying is not correct. The filter() function automatically 'AND's its parameters. See the documentation on filter

Solution 2

You can use Q objects to handle more complex queries. See django docs about Q objects

from django.db.models import Q

q.filter(
    Q(answer__code=code) & Q(answer__value=value)
)
Share:
10,830

Related videos on Youtube

sbarzowski
Author by

sbarzowski

Updated on June 04, 2022

Comments

  • sbarzowski
    sbarzowski about 2 years

    EDIT: This question is a result of misunderstanding of the observed results. The snippet that was originally posted and not working solves the problem. I'm leaving it all below for anyone in the future who gets confused in the same way.

    I have two models answer and answer_set. I need to write a function that takes answer_set queryset and adds a filter.

    The filter I want to apply is: answer_set has an answer with specific code and value.

    At first I tried something like:

    q.filter(answer__code=code, answer__value=value)
    

    But of course that doesn't work - these are two separate answers (two joins in SQL), i.e. the filter condition is true if there is some answer with the right code and another one with the right value. I want to check if there is a single answer that satisfies both conditions. EDIT: And this code actually does exactly what I want.

    In SQL that would be very easy:

    ...
    JOIN answer
    ...
    WHERE
    ...
    answer.value = "some_value" AND answer.code = "some_code"
    

    But I consider raw SQL last resort. Can it be done in Django ORM? EDIT: Yes, it does - see the snippet above.

    • Todor
      Todor
      Show us the models and how you construct the query. It really matters if you use .filter(answer__code=code, answer__value=value) or .filter(answer__code=code).filter(answer__value=value). The second approach should act as you describe it (two inner joins), but the 1st one should use a single join.