Django ORM 每位作者的书籍数量

3 投票
3 回答
2007 浏览
提问于 2025-04-19 08:10
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)

我想知道有多少本书是注册在某个作者名下。假设我有作者A1、A2和A3。

一本书可以有多个作者。我有书籍B1、B2和B3。

我想知道有多少本书是作者A1的,假设他有2本书。

已经尝试过的

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

哪个方法更好?

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)

有没有其他更有效的方法?

3 个回答

1

这里有个简单的解决办法:

Author.objects.annotate(count=Count('book_set'))

然后你可以遍历它,并把“count”当作一个属性来使用。更多关于“book_set”的信息

4

在Django中,所有的对象都有一个内置的反向关系,这样你就可以“往回走”和“往前走”。这是什么意思呢?简单来说,一旦你有了一个作者的信息,你就可以这样做:

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

如果你想获取所有作者的数量,可以这样做:

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

给相关名称

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

然后

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

#auth_books are all books which belong to one author

或者

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

这会给你所有作者是指定作者的书籍。

如果你想知道所有作者的书籍

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

这会给你所有在数据库中存在的作者的书籍。

想知道有多少本书:只需在结果后面加上 .count()。

撰写回答