Django ORM Number of books per author

class Author(models.Model):
   name = models.CharField(max_length=100)
   age = models.IntegerField()
   friends = models.ManyToManyField('self', blank=True)

class Publisher(models.Model):
   name = models.CharField(max_length=300)
   num_awards = models.IntegerField()

class Book(models.Model):
   isbn = models.CharField(max_length=9)
   name = models.CharField(max_length=300)
   pages = models.IntegerField()
   price = models.DecimalField(max_digits=10, decimal_places=2)
   rating = models.FloatField()
   authors = models.ManyToManyField(Author)
   publisher = models.ForeignKey(Publisher)
   pubdate = models.DateField()

class Store(models.Model):
   name = models.CharField(max_length=300)
   books = models.ManyToManyField(Book)

      

I am looking to see how many books are registered with the author. Let's say I have an author A1, A2, A3.

One book may belong from multiple authors.

I have books, B1, B2, B3

I want to know how many books are by A1. let's say it belongs to two books.

Tried already

Author.objects.all()
Books.objects.filter(authors=43).count()
2

      

Which one is better?

for auth in authors:
  book.count =book.book_auths.count()
  book_counts_alternative_way = Book.objects.annotate(num_count=Count('book_auths')).filter(book_auths=tech, num_count__gt=0)

      

Any other efficient way?

+3


source to share


2 answers


Give a related name

authors = models.ManyToManyField(Author, related_name='book_auths')

      

Then

author = Author.objects.get(id=43)
auth_books = author.book_auths.all()

#auth_books are all books which belong to one author

      

or

author = Author.objects.get(id=43)  
books = Book.objects.filter(author=author) 

      



Gives all books where the author is given.

Or if you want to know all the authors

authors = Authors.objects.all()
books = Book.objects.filter(author__in=(x for x in authors))

      

Gives you all books that have authors that exist in db.

To find out how much: just attach .count () to trigger the request.

+3


source


All django objects have feedback built in, so you can go back and forth. This means that if you have an author, you can do this:

a = Author.objects.get(name='A1 Author')
a.book_set.count()

      



Get counters for all authors:

for a in Author.objects.all():
   print('Author: {} - Number of Books: {}'.format(a, a.book_set.count()))

      

+3


source







All Articles