Django filter multiple values
Question:
Anyone know why this query_set
doesn’t return any values for me? Using filter separately, it works perfectly, so it seems .filter().filter()
together is the wrong approach to filter for ‘either or’.
ticket_query = request.event.tickets.filter(status='on-sale').filter(status='paused').prefetch_related('ticket_tax')
Answers:
filter() with multiple parameters joins them with AND statements:
https://docs.djangoproject.com/en/2.0/ref/models/querysets/#filter
To perform OR queries in django you can use Q objects:
from django.db.models import Q
ticket_query = request.event.tickets.filter(Q(status='on-sale') | Q(status='paused')).prefetch_related('ticket_tax')
More details here:
https://docs.djangoproject.com/en/2.0/topics/db/queries/#complex-lookups-with-q
Chaining filter
like you have done applies the subsequent filter to the queryset returned by the previous filter, i.e. it acts like an AND condition, not OR.
You can use the |
operator to combine two queries:
ticket_query = request.event.tickets.filter(status='on-sale') | request.event.tickets.filter(status='paused')
request.event.tickets.filter(status='on-sale')
returns all objects with status='on-sale'
, and you are looking for objects with status='paused'
in that list, which is why you are getting an empty queryset.
Chaining 2 filters is fine if it is a ManyToManyField
where you can have multiple objects for the same field OR if you are chaining for 2 separate fields eg. request.event.tickets.filter(status='on-sale').filter(is_available=True)
, which returns all tickets that are on sale and are available.
The simplest approach for this problem would be to use __in
in the filter like this: ticket_query = request.event.tickets.filter(status__in=['on-sale', 'paused']).prefetch_related('ticket_tax')
.
Hope this helps. 🙂
Anyone know why this query_set
doesn’t return any values for me? Using filter separately, it works perfectly, so it seems .filter().filter()
together is the wrong approach to filter for ‘either or’.
ticket_query = request.event.tickets.filter(status='on-sale').filter(status='paused').prefetch_related('ticket_tax')
filter() with multiple parameters joins them with AND statements:
https://docs.djangoproject.com/en/2.0/ref/models/querysets/#filter
To perform OR queries in django you can use Q objects:
from django.db.models import Q
ticket_query = request.event.tickets.filter(Q(status='on-sale') | Q(status='paused')).prefetch_related('ticket_tax')
More details here:
https://docs.djangoproject.com/en/2.0/topics/db/queries/#complex-lookups-with-q
Chaining filter
like you have done applies the subsequent filter to the queryset returned by the previous filter, i.e. it acts like an AND condition, not OR.
You can use the |
operator to combine two queries:
ticket_query = request.event.tickets.filter(status='on-sale') | request.event.tickets.filter(status='paused')
request.event.tickets.filter(status='on-sale')
returns all objects with status='on-sale'
, and you are looking for objects with status='paused'
in that list, which is why you are getting an empty queryset.
Chaining 2 filters is fine if it is a ManyToManyField
where you can have multiple objects for the same field OR if you are chaining for 2 separate fields eg. request.event.tickets.filter(status='on-sale').filter(is_available=True)
, which returns all tickets that are on sale and are available.
The simplest approach for this problem would be to use __in
in the filter like this: ticket_query = request.event.tickets.filter(status__in=['on-sale', 'paused']).prefetch_related('ticket_tax')
.
Hope this helps. 🙂