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
CodePudding user response:
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>
CodePudding user response:
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'))