Package: django-prefetch
Simple and generic model related data prefetch framework for Django solving the “1+N queries” problem that happens when
you need related data for your objects.In most of the cases you’ll have forward relations (foreign keys to something)
and can use select_related to fetch that data on the same query. However, in
some cases you cannot design your models that way and need data from reverse
relations (models that have foreign keys to your objects).Django hasprefetch_relatedfor this, however, this framework provides greater
flexibility than Django’sprefetch_relatedqueryset method at the cost
of writting the mapping and query functions for the data. This has the advantage
that you can do thingsprefetch_relatedcannot (see the latest_bookexamplebelow).Free software: BSD licenseInstallation guideInstall it:pip install django-prefetchUse it as your model’s default manager (or as a base class if you have custom
manager).RequirementsOS:AnyRuntime:Python 2.7, 3.3+ or PyPyPackages:Django>=1.9ExampleHere’s a simple example of models and prefetch setup:from django.db import models
from prefetch import PrefetchManager, Prefetcher

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

    objects = PrefetchManager(
        books = Prefetcher(
            filter = lambda ids: Book.objects.filter(author__in=ids),
            reverse_mapper = lambda book: [book.author_id],
            decorator = lambda author, books=(): setattr(author, 'books', books)
        ),
        latest_book = Prefetcher(
            filter = lambda ids: Book.objects.filter(author__in=ids),
            reverse_mapper = lambda book: [book.author_id],
            decorator = lambda author, books=(): setattr(
                author,
                'latest_book',
                max(books, key=lambda book: book.created) if books else None
            )
        )
    )

class Book(models.Model):
    class Meta:
        get_latest_by = 'created'

    name = models.CharField(max_length=100)
    created = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(Author)Use it like this:for a in Author.objects.prefetch('books', 'latest_book'):
    print a.books
    print a.latest_bookPrefetcher argumentsExample models:class LatestNBooks(Prefetcher):
    def __init__(self, count=2):
        self.count = count

    def filter(self, ids):
        return Book.objects.filter(author__in=ids)

    def reverse_mapper(self, book):
        return [book.author_id]

    def decorator(self, author, books=()):
        books = sorted(books, key=lambda book: book.created, reverse=True)
        setattr(author,
                'latest_%s_books' % self.count,
                books[:self.count])

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

    objects = PrefetchManager(
        latest_n_books = LatestNBooks
    )Use it like this:from prefetch import P

for a in Author.objects.prefetch(P('latest_n_books', count=5)):
    print a.latest_5_bookNotePis optional and you can only use for prefetch definitions that are Prefetcher subclasses. You can’t use it with prefetcher-instance style
definitions like in the first example. Don’t worry, if you do, you will get an exception explaining what’s wrong.Other examplesCheck out the tests for more examples.TODODocumentcollectoption ofPrefetcherCreate tests covering customcollectandmapperDevelopmentTo run all the tests run:toxNote, to combine the coverage data from all the tox environments run:Windowsset PYTEST_ADDOPTS=--cov-append
toxOtherPYTEST_ADDOPTS=--cov-append toxChangelog1.2.3 (2021-06-01)Now support any primary key in master table with default mapper, not only “id” column.
Contributed by Stas Fomin in#20.1.2.2 (2021-04-11)Added support for Django 2.01.2.1 (2018-09-04)Fixed missing entry in changelog.1.2.0 (2018-09-04)Added support for Django 1.11, dropped support for Django <1.9. Contributed by Martin Bachwerk in#16.1.1.0 (2016-02-20)Fixed a test assertion. Contributed by George Ma in#12.Added support for Django 1.9. Contributed by Will Stott in#14.Fixed use of deprecatedfield.rel.tomomdel API (Django 1.9+).1.0.1 (2015-09-05)Fixed manager type check. Contributed by George Ma in#11.1.0.0 (2014-12-05)Fixed issues withselect_relatedbeing removed when prefetch is used (#9).