Add backward one-to-many relationship to queryset

Hi everyone!
I have two models, Profile and Photo. Photo model have a ForeignKey field addressing to Profile model. One profile can have from zero to unlimited photos. I need to display a list of all profiles with photos for each profile, like this:

profile1
photo1 photo2 photo3

profile2
photo4 photo5

I found a way to make “backwards” queries to related objects (Making queries | Django documentation | Django), but I cannot understand how can I add this data to queryset. For now my code is:

models.py:

class Profile(models.Model):   
    some fields...

class Photo(models.Model):
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
    some fields...

views.py:

# can I get photos for profiles in one query, or there is only one way to loop over profiles and make subqueries?
profiles = Profile.objects.all()
for profile in profiles:
    profile.photo_set.all()
    # this data is received, but how can I add it to profiles queryset?

You don’t.

What is it that you’re looking to do with this that is making you think this is necessary?

:slightly_smiling_face: I’m just trying to pass data to template, to render somthing like this:

profile1
photo1 photo2 photo3

profile2
photo4 photo5

Then you access this as the attribute in your template.

If your context variable is named profile, then you can iterate over profile.photo_set.all in the template.

Side note: In any of these types of situations, you may wish to use the “prefetch_related” function in your original query to avoid “N + 1” query conditions. It’s not required, but it is a potentially-significant performance improvement.

Thank you very much, Ken! It works

It seems I’m using it in wrong way, because with this code:

profiles = Profile.objects.all().prefetch_related("photo_set")

I’m getting “profiles.Photo.None” as value of profile.photo_set in iterated profiles queryset

You still need to iterate over profile.photo_set.all in the template.

1 Like