用于django的简单且通用的模型相关数据预取框架,用于解决当您需要对象的相关数据时发生的“1+n查询”问题。
django-prefetch的Python项目详细描述
用于django的简单通用模型相关数据预取框架,用于解决以下情况下发生的“1+n查询”问题 您需要对象的相关数据。
在大多数情况下,你会有向前的关系(某事物的外键) 并且可以使用select_related在同一个查询上获取该数据。然而,在 有些情况下,你不能这样设计你的模型,需要反向的数据 关系(对象具有外键的模型)。
Django为此提供了prefetch_related,但是,这个框架提供了 比Django prefetch_related QuestSub方法在成本上的灵活性 为数据编写映射和查询函数。这有好处 你可以做prefetch_related不能做的事情(请参阅最新的example 吼叫)。
- 免费软件:BSD许可证
安装指南
安装:
pip install django-prefetch
将其用作模型的默认管理器(如果有自定义的 经理)。
要求
OS: | Any |
---|---|
Runtime: | Python 2.7, 3.3+ or PyPy |
Packages: | Django>=1.9 |
示例
下面是一个简单的模型和预取设置示例:
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) ) ) ) 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)
像这样使用:
for a in Author.objects.prefetch('books', 'latest_book'): print a.books print a.latest_book
预取参数
示例模型:
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 )
像这样使用:
from prefetch import P for a in Author.objects.prefetch(P('latest_n_books', count=5)): print a.latest_5_book
注意
P是可选的,只能用于预取器子类的预取定义。不能与预取器实例样式一起使用 定义与第一个示例类似。别担心,如果你这样做了,你会得到一个解释错误的例外。
其他示例
查看测试以获取更多示例。
待办事项
- 文档collect选项Prefetcher
- 创建覆盖自定义collect和mapper 的测试
更改日志
1.2.1(2018-09-04)
- 修复了更改日志中缺少的条目。
1.2.0(2018-09-04)
- 增加了对django 1.11的支持,减少了对django<;1.9的支持。Martin Bachwerk在 #16。
1.1.0(2016-02-20)
1.0.1(2015-09-05)
- 固定管理器类型检查。马英九在#11中撰稿。
1.0.0(2014-12-05)
- 修复了使用预取(#9)时删除select_related的问题。