1

I have a page which lists the posts along with the photos associated with each post. However I am having trouble in filtering and sending photos from photo lists QuerySet as it us under loop of posts list query set. Any idea how to run filters for getting the photos as only the associated post in a template?

<h2> Posts: </h2>
{% for post in post_list %}

     {% include 'posts/list-inline.html' with post_whole=post  post_photos=photo_list %}

{% endfor %}

Here from photo_list in need to filter out multiple objects having foreign key relationship with individual post. The QuerySet filter is not working here in the template.

Update: The shrunken down models for reference:

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_text = models.CharField(max_length=5000, null=True, blank=True)
    selection = models.ForeignKey(Selection, null=True, blank=False, on_delete=models.SET_NULL)
    timestamp = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

class PostPhoto(models.Model):
    # to apply multiple photos to same post id
    post_id = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
    photo = models.ImageField(upload_to='img/', blank=True, null=True)
    thumbnail = models.ImageField(upload_to='tmb/', null=True, blank=True, editable=False)
2
  • Please share the relavant models. Commented Apr 26, 2020 at 17:45
  • @WillemVanOnsem I have edited and added the models relevant. Commented Apr 26, 2020 at 18:00

1 Answer 1

2

You can obtain the lists of related PostPhoto objects with:

mypost.postphoto_set.all()

So in your template, you can render this with:

<h2> Posts: </h2>
{% for post in post_list %}
     {% include 'posts/list-inline.html' with post_whole=post  post_photos=post.postphoto_set.all %}
{% endfor %}

(without brackets, since the template will automatically call a callable).

To avoid the N+1 problem, in the view, you better retrieve the Posts with a .prefetch_related(..) clause [Django-doc]:

posts = Post.objects.prefetch_related('postphoto_set')
Sign up to request clarification or add additional context in comments.

8 Comments

The issue is that the post_list contains multiple posts.... Out of those multiple posts, each post has multiple photos... So in this template all I am getting from the view is a QuerySet of multiple posts objects under post_list and a related QuerySet of multiple PostPhoto objects under photo_list.
@Jayesh: in the list-inline.html, you need to iterate over the post_photos, and thus render these invididually.
oh I missed the post before the dot .... It worked ... Thanks... Though I fully don't understand the N+1 problem that you are speaking about...
@Jayesh: if you render n posts, it would result in n+1 queries: one to fetch the post, and n to fetch the PostPhotos of the Post objects. By using .prefetch_related. Django will use one extra query to fetch all the related PhotoPosts in memory and then do the joining at the Django/Python level. So instead of n+1 queries, you perform two queries.
that sound's great for performance point of view. I'll try to do that now...
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.