Assume I have two models:
A:
pass
B:
a = foreign_key(A)
Now, I have a query set
bs = B.objects.filter(...)
I want to get all the a
of bs
, which means every a
which is referenced by b
for which b
is in bs
.
Is there a way to do so? I think in sql, a simple join will do, I don't know if django support this.
annotate() that has been computed over the objects that are related to the objects in the QuerySet . Each argument to annotate() is an annotation that will be added to each object in the QuerySet that is returned. The aggregation functions that are provided by Django are described in Aggregation Functions below.
Using select_related() Django offers a QuerySet method called select_related() that allows you to retrieve related objects for one-to-many relationships. This translates to a single, more complex QuerySet, but you avoid additional queries when accessing the related objects.
You can use __in
:
A.objects.filter(b__in=bs)
or you can avoid creating the bs queryset at all, and follow the relation directly in your query:
A.objects.filter(b__<bcondition>=<bvalue>)
For example, if the filter used to create bs
was:
bs = B.objects.filter(name="Banana")
Then you could filter the A
objects using:
A.objects.filter(b__name="Banana")
Bear in mind that there are a number of different ways you can filter, and that the filter functionality is quite extensive, so it is worth reviewing the filter documentation
Extending Daniel's solution, using __in
might return duplicate records if using a related model.
For example:
A.objects.filter(b__in=bs).count()
could be more than A.objects.all().count()
For me, using distinct()
worked as mentioned in this SO answer
A.objects.filter(b__in=bs).distinct()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With