Django ORM:为每个外键获取第一个实例

时间:2018-08-16 19:58:12

标签: sql django-models

我有以下型号:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    number = models.IntegerField()

某些作者可能没有书。有没有办法获取至少在Book上写过的每位作者仅包含一本书的列表或集?我正在寻找一个SQL事务解决方案。

例如,如果我有以下条目:

作者:

  • 阿尔伯特·加缪
  • 弗里德里希·尼采
  • 西格蒙德·弗洛伊德

书籍:

  • 尼采(Nietzsche)所说的话Zarathustra
  • 加缪的西西弗斯神话
  • 加缪斯的叛军

我想要一个查询,该查询返回[Thus Spoke Zarathustra,西西弗斯神话]或[Thus Spoke Zarathustra,叛逆者]。

查询的奖励点将返回number最低的书籍。

2 个答案:

答案 0 :(得分:1)

您将不得不使用原始查询。像这样:

query='''
SELECT b1.id, b1.title, b1.author_id, b1.number from Books_book b1, (
    SELECT author_id, min(number) as min_number
    from Books_book
    GROUP BY author_id
) as b2
WHERE b1.author_id=b2.author_id AND b1.number = b2.min_number
'''
books_list = Book.objects.raw(query)[:]

现在books_list根据需要为每位作者提供一本书(编号最少)

答案 1 :(得分:1)

例如,您应该可以使用Subquery来实现此目标

from django.db.models import OuterRef, Subquery

books = Book.objects.filter(author_id=OuterRef('pk')).order_by('number')
authors = Author.objects.annotate(book_title=Subquery(books.values('title')))

for author in authors:
    print(author.name, author.book_title)