Как фильтровать объекты, связанные с fk, на django

Я хочу запросить книги, которые конкретный человек одолжил на данный момент. Я использую этот запрос Book.objects.filter(lends__person__username__iexact="Antony"), но он не работает должным образом.

Что я хочу получить:

  • книги с последним именем пользователя человека, который давал в долг. (не те, кто одалживал до последнего)

вот мои модели

class Person(models.Model):
    username = models.CharField(max_length=32, unique=True)


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


class Lends(models.Model):
    book = models.ForeignKey(
        "Book", on_delete=models.CASCADE, related_name="lends"
    )
    person = models.ForeignKey(
        "Person", on_delete=models.CASCADE, related_name="lends"
    )

Вы ищете временную информацию. Я рекомендую вам добавить поле created_at в класс Lends. Этот атрибут будет заполняться автоматически при каждом создании объекта. С его помощью вы сможете сортировать в порядке убывания.

class Lends(models.Model):
    book = models.ForeignKey(
        "Book", on_delete=models.CASCADE, related_name="lends"
    )
    person = models.ForeignKey(
        "Person", on_delete=models.CASCADE, related_name="lends"
    )
    created_at = models.DateTimeField(auto_now_add=True)

Итак, сейчас вы можете фильтровать и упорядочивать набор запросов.

last_lend = Lends.objects.filter(lends__person__username__iexact="Antony").order_by("-created_at").first()

Посмотреть, как работает упорядочивание, можно здесь: https://docs.djangoproject.com/en/4.1/ref/models/options/#:~:text=initial%20migrate.-,ordering,-%C2%B6

что я хочу получить:
книги с последним именем пользователя человека, который дал в долг. (не те, кто одалживал до последнего)

это можно сделать с помощью Subquery

from django.db.models import OuterRef, Subquery

latest_lended_person = Lend.objects.filter(
    book=OuterRef('pk')
).order_by('-pk')

books = Book.objects.annotate(
    latest_lended_person_username=Subquery(
        latest_lended_person.values('username')[:1]
    )
)
Вернуться на верх