Reputation: 35089
I have the following models:
class Collection(models.Model):
# some fields here ...
class Entry(models.Model):
collection = models.ForeignKey(Collection, reverse_name="entries")
start_time = models.DateTimeField()
end_time = models.DateTimeField()
Now I want to query all Collection
s that have at least one Entry
associated which I do with (quite quirky, I think):
collections_qs = Collection.objects.annotate(
entry_count=Count('entries')
).filter(entry_count__gt=0)
Which works quite well. But I want to combine this query with a date/time window search given by the two datetime
s start
and end
. What I've come up with was:
if start:
collections_qs = collections_qs.filter(entries__start_time__gte=start)
if end:
collections_qs = collections_qs.filter(entriess__end_time__lte=end)
But that just rearranges the order of the returned Collection
s but not the content. How can I achieve the date/time search (preferably with just one query)?
Upvotes: 1
Views: 224
Reputation: 1984
For reverse FK (and ManyToMany fields too), there is a difference between
.filter(a=b, x=y)
and .filter(a=b).filter(x=y)
(see doc).
What you need when you have both start
and end
conditions is the filter(.,.)
one that will get you the Collections
that have at least one Entry
that verifies both condition.
Also, Collection.objects.filter(entries__isnull=False).distinct()
seems more readable than .annotate(entry_count=Count('entries')).filter(entry_count__gt=0)
.
Finally, when you have at least one condition on entries
, you don't need to have any filter to check for the existence of such entries.
Upvotes: 1