Модель Django: Получение результата из таблицы с использованием уникального внешнего ключа

#sql #django #django-models #django-queryset

Вопрос:

У меня есть две модели, которые выглядят так:

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

class Book(models.Model):
    author = models.ForeignKey('Author', on_delete=models.CASCADE)
    isbn_id = models.CharField(max_length=50, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
 

Как я могу сделать запрос таким образом, чтобы:

  1. Я получаю каждого автора с общим количеством созданных книг, количеством книг с isbn.
  2. Каждый раз, когда книга создается для автора, я могу получить last_created, last_modified.

Это пример результата, которого я пытаюсь достичь;

 s/n| author| no_books_with_isbn| all_books| last_created| last_modified
1.  Faye        2                   2       ...             ....
2.  Soya        2                   5
3.  Jake        6                   6
4.  Gurj        4                   4
5.  Zoom        2                   10
 

Ответ №1:

Вам нужно annotate много агрегаций для вашего набора запросов (Ссылка: Агрегация [Документы Django]). Чтобы получить подсчеты, вы можете использовать функцию Count [Django Docs], а для last_created / last_modified вы можете использовать функцию Max [Django Docs] для достижения желаемого:

 from django.db.models import Count, Max, Q


queryset = Author.objects.annotate(
    all_books=Count('book'),
    no_books_with_isbn=Count(
        'book',
        filter=Q(book__isbn_id__isnull=False)
    ),
    last_created=Max('book_created_at'),
    last_modified=Max('book_updated_at')
)


for author in queryset:
    print(author.name, author.no_books_with_isbn, author.all_books, author.last_created, author.last_modified)