I found a way to make using the above strategy more pleasant:
class WithConnection:
def __init__(self, queryset):
self.queryset = queryset
def __iter__(self):
for model in self.queryset:
connection = model.my_connections[0] if model.my_connections else None
yield model, connection
class InvestorQuerySet(models.QuerySet):
def pov(self, advisor):
return WithConnection(
self.prefetch_related(models.Prefetch(
'connections',
queryset=Connection.objects.filter(advisor=advisor),
to_attr='my_connections',
))
)
Used like this:
advisor = Advisor.objects.first()
for investor, connection in Investor.objects.pov(advisor):
# do stuff with investor
if connection:
# do stuff with connection
Would like to improve on this. Django’s ORM is so powerful, seems like there ought to be a simpler way to achieve this.
PS - I first tried subclassing ModelIterable and setting self._iterable_class to it in pov(), but Django would call my iterable on the models before during the second pre-fetch query, so my code failed when trying to access the my_connections attribute.
advisor = Advisor.objects.first()
for investor, connection in Investor.viewed_by(advisor).filter(age__gt=40):
# do stuff with investor
if connection:
# do stuff with connection