Django - 使用第一个过滤的相关对象进行注释

时间:2021-01-18 16:21:38

标签: python django django-models django-orm

有模型:

class Book(models.Model):
    name = models.CharField(max_length=255)

class Page(models.Model): 
    text = models.TextField()
    page_number = models.PositiveSmallIntegerField()
    book = models.ForeignKey(Book, on_delete=models.CASCADE)

我想根据页码的变化用 selected_page 注释书籍。
没有必需页码的书籍将有 book.selected_page == None:

page_number = get_page_number()
books = Book.objects.annotate(???)
# smthing like: Book.objects.annotate(selected_page=Page.objects.filter(page_number=page_number).first())
for book in books:
    if book.selected_page:
        print(book.selected_page.text)

1 个答案:

答案 0 :(得分:0)

您正在寻找 SubqueryOuterRefhttps://docs.djangoproject.com/en/3.1/ref/models/expressions/#subquery-expressions

from django.db.models import OuterRef, Subquery
selected_page = Page.objects.filter(
    book_id=OuterRef('id'),
    page_number=page_number,
)

books = Book.objects.annotate(
    selected_page_text=Subquery(selected_page.values('text')[:1]),
)
print(books.first().selected_page_text)