This works but is very slow. I have an Author table that foreign keys to all books by that author. Each book has a variety of formats it can appear in (html, pdf, etc), which its linked to by its own foreign key.
As the code shows, what I'm doing now is getting all the authors, then looping through to get each book by the author, and looping through those to get all the format types of each book. If the book does not have all four types, it's appended to a list of dictionaries to be displayed in the template.
Note that checking simply the count of each format would be insufficient, as it's possible a book might have multiple versions of one type; I need to make sure each type appears at least once.
We have tens of thousands of authors, each of which can have up to about 20 books, each of which can have up to about 5-8 formats max.
def missing_book_format_report(request):
authors = Author.objects.all()
data = []
for author in authors:
books = author.book_set.all()
for book in books:
book_info = {
"book_num": book.num,
"type": book.short_name,
"xml": False,
"pdf": False,
"html": False,
"gen_html": False
}
book_formats = book.format_set.all()
for book_format in book_formats:
format_type = book_format.format_type_cd_id.lower() # e.g. xml
book_info[format_type] = True
if not all([book_info["xml"], book_info["pdf"], book_info["html"], book_info["gen_html"]]):
data.append(book_info)
context = {
'data': data,
'books': books
}
return render(request, 'book-report.html', context)
prefetch_related
is already implemented; I mistakenly left it out of the code. \$\endgroup\$