0

I have these models:

class Source(models.Model):
    name          = models.CharField(max_length=255, blank=True, null=True)
    feed_url      = models.CharField(max_length=512)
    ....

class Post(models.Model):
    source        = models.ForeignKey(Source, on_delete=models.CASCADE, related_name='posts')
    title         = models.TextField(blank=True)
    body          = models.TextField()
    ....

class FeedCategory(models.Model):
    feed_category = models.CharField(max_length=128, choices=FEED_CATEGORIES, blank=True)
    source = models.ForeignKey(Source, on_delete=models.CASCADE)

And I want to make a Queryset where I get all FeedCategories but I'd like to also include in there their related posts. So If I use:

    feeds = FeedCategory.objects.select_related('source').all()

my queryset does not return the posts. I tried using:

    feeds = FeedCategory.objects.select_related('source').all()
    posts = Post.objects.filter(source_id__in=feeds.values_list('source_id', flat=True))

which works but its on two different queries. What I basically want to do is have a single query which shows the category and the related source's posts in order to bring them up on frontend so I could use something like:

{% for feed in feeds %} 
   {{feed.category}}
   {% for post in feed.source_set %}
       {{post.body}}
   {% endfor %}
{% endfor %}

My thinking was something with annotate but how exactly do I do that?

haduki
  • 1,145
  • 5
  • 23

1 Answers1

0

First of all: In for post in feed.source_set source_set contains Source objects. Not Posts. You need to go deeper since there could be many Posts in one Source and there can be manu Sources in one FeedCategory

{% for feed in feeds %} 
   {{feed.category}}
   {% for source in feed.source_set.all %}
       {% for post in source.posts.all %}
           {{post.body}}
       {% endfor %}
   {% endfor %}
{% endfor %}

About the query. I'm almost sure you can't do that insingle query. This is possible only if there is single foreign key. Since you can have many connection then you should use prefetch_related

Try:

feeds = FeedCategory.objects.prefetch_related('source', "source__posts").all()

This should do at most 3 queries if I'm not missing something

Bartosz Stasiak
  • 1,415
  • 1
  • 4
  • 9