Django ORM每位作者的书籍数量

时间:2014-09-02 06:36:28

标签: python django orm

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。

One book may belong from multiple authors. 我有书,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 个答案:

答案 0 :(得分: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()))

答案 1 :(得分:3)

将related_name设为

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))

为您提供所有在db中存在作者的书籍。

要知道多少:只需将.count()附加到结果查询集。

答案 2 :(得分:1)

这里有一个简单的解决方案:

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

然后您可以对其进行迭代,并将“ count”作为属性。 More关于“ book_set”