4

I have a simple model like

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name



class Blog(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

Here I want to queryall authors with the title of all the blogs they have written like

Author One : [Blog One, Blog Two, Blog Three]

I want this from query and not loop

Here my approach is to use subquery like

blogs =Blog.objects.filter(author=OuterRef('pk')).values("title")
authors = Author.objects.annotate(blogs=Subquery(blogs), output_field=CharField())

But here I am getting error like sub-select returns 2 columns - expected 1

How can I get all the authors with all the blogs they have written ? I do not want to use loop. I want this through query

3
  • Eventually it will go through a loop that will make a list. Usually it is not a good idea to do string processing in the database. Commented Feb 28, 2022 at 16:26
  • @WillemVanOnsem its ok if not string. I works for me if it is list. Updated the question Commented Feb 28, 2022 at 16:35
  • but the same comment holds for a list or any other collection. Commented Feb 28, 2022 at 16:36

2 Answers 2

4

If you are using a postgres as a database, then you can use an ArrayAgg function:

from django.contrib.postgres.aggregates import ArrayAgg

authors = Author.objects.annotate(blogs=ArrayAgg('blog_set__title'))
Sign up to request clarification or add additional context in comments.

2 Comments

great.. just the thing is you can only do ArrayAgg('blog__title')).. you dont need set here.. thank you
@GreenPanda hi, mark the post as resolved, if it really helped you, thanks
2

You can query with:

authors = Author.objects.prefetch_related('blog_set')

Then in the template, you can render with:

<ul>
  {% for author in authors %}
    <li>{{ author }}</li>
    <ul>
      {% for blog in author.blog_set.all %}
        <li>{{ blog }}</li>
      {% endfor %}
    </ul>
  {% endfor %}
</ul>

1 Comment

I dont need this in template.. I just want the result of query in list

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.