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.
Project description
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 has prefetch_related for this, however, this framework provides greater flexibility than Django’s prefetch_related queryset method at the cost of writting the mapping and query functions for the data. This has the advantage that you can do things prefetch_related cannot (see the latest_book example below).
Free software: BSD license
Installation guide
Install it:
pip install django-prefetch
Use it as your model’s default manager (or as a base class if you have custom manager).
Requirements
- OS:
Any
- Runtime:
Python 2.7, 3.3+ or PyPy
- Packages:
Django>=1.9
Example
Here’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_book
Prefetcher arguments
Example 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_book
Other examples
Check out the tests for more examples.
TODO
Document collect option of Prefetcher
Create tests covering custom collect and mapper
Development
To run all the tests run:
tox
Note, to combine the coverage data from all the tox environments run:
Windows |
set PYTEST_ADDOPTS=--cov-append tox |
---|---|
Other |
PYTEST_ADDOPTS=--cov-append tox |
Changelog
1.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.0
1.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)
1.0.1 (2015-09-05)
Fixed manager type check. Contributed by George Ma in #11.
1.0.0 (2014-12-05)
Fixed issues with select_related being removed when prefetch is used (#9).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-prefetch-1.2.3.tar.gz
.
File metadata
- Download URL: django-prefetch-1.2.3.tar.gz
- Upload date:
- Size: 24.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a232a63fa6c244fd14a1f1649052e3201476858dffa3f37875e13c032a09cdf4 |
|
MD5 | 5e9ac0f35fb91d87390a6fbff2d28232 |
|
BLAKE2b-256 | e54fe668b12b6227bf671db9ccaf3b113d2f530e784fa127f045805664fb7f5f |
File details
Details for the file django_prefetch-1.2.3-py2.py3-none-any.whl
.
File metadata
- Download URL: django_prefetch-1.2.3-py2.py3-none-any.whl
- Upload date:
- Size: 7.5 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6059c24ddbb896a0413caea5d9e5f08154882f5049c077cb936c9b817022b6ef |
|
MD5 | c21bbc3117c86ffddd51bbc3ae3e903b |
|
BLAKE2b-256 | ebf79d212f52357ce3566763a15e7aa4c269f543436b5cc4eb8d41307b44c912 |