Reputation: 10564
class Author(models.Model):
name = models.CharField()
class Article(models.Model):
author = models.ForeignKey(Author)
let's suppose I need to show in a template how many Articles
are from a determinate author. This is the view:
def myview(request):
context = {
'authors': Author.objects.all()
}
simply doing {{ author.Articles||length }}
would require me to edit the Author model. If this is the correct way (it obviously isn't), should I do this at the models.py
level or in the view myview
?
I believe that editing the model in models.py
would result in a really bad code design.
Doing so in myview
would require me to do something like this:
authors = []
for author in authors:
count = Article.objects.filter(author__exact=author).count()
authors.append(author, count)
horrendously_bad_code_design_context = {
'authors': authors,
}
What is the correct way to do so? I believe that both these implementations are really bad and 'hacky'.
Upvotes: 2
Views: 1198
Reputation: 6013
If you already have a retrieved author and you want to get the article count then using the related manager's count
method (author.article_set.count()
) is probably okay.
On the other hand if you are iterating over an (possibly lagre) Author
queryset just to get the counts, it will do a lot of queries (one to retrieve all authors and one per author to get the count). This can be easily replaced by an annotated queryset that will result in only one query:
from django.db.models import Count
Author.objects.annotate(article_count=Count('articles'))
Later on in your in your template you can just use {{ author.article_count }}
.
Upvotes: 3