跳转到主要内容

Django的简单通用模型相关数据预取框架,解决您需要为对象获取相关数据时出现的“1+N查询”问题。

项目描述

为Django提供简单通用的模型相关数据预取框架,解决您需要为对象获取相关数据时出现的“1+N查询”问题。

在大多数情况下,您将具有正向关系(指向某物的外键)并可以使用select_related在相同查询中获取该数据。然而,在某些情况下,您不能以这种方式设计您的模型,并需要从反向关系(具有指向您的对象的外键的模型)获取数据。

Django 提供了 prefetch_related 功能,然而,这个框架在编写数据映射和查询函数的代价下,提供了比 Django 的 prefetch_related 查询集方法更大的灵活性。这具有优势,您可以进行 prefetch_related 无法完成的事情(请参阅下方的最新书籍 示例)。

  • 自由软件:BSD 许可证

安装指南

安装它

pip install django-prefetch

将其用作您模型默认的管理器(或者如果您有自定义管理器,则作为基类)。

需求

操作系统:

任意

运行时:

Python 2.7、3.3+ 或 PyPy

:

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) 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)

使用方法如下

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

其他示例

查看测试以获取更多示例。

待办事项

  • 记录 Prefetchercollect 选项

  • 创建涵盖自定义 collectmapper 的测试

开发

要运行所有测试,请运行

tox

注意,要组合来自所有 tox 环境的覆盖率数据,请运行

Windows

set PYTEST_ADDOPTS=--cov-append
tox

其他

PYTEST_ADDOPTS=--cov-append tox

变更日志

1.2.3 (2021-06-01)

  • 现在支持主表中任何主键,默认情况下使用映射器,而不仅仅是“id”列。由 Stas Fomin 在 #20 贡献。

1.2.2 (2021-04-11)

  • 添加了对 Django 2.0 的支持

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)

  • 修复了一个测试断言。由 George Ma 在 #12 贡献。

  • 添加了对 Django 1.9 的支持。由 Will Stott 在 #14 贡献。

  • 修复了使用已弃用的 field.rel.to 模型 API(Django 1.9+)的问题。

1.0.1 (2015-09-05)

  • 修复了管理器类型检查。由 George Ma 在 #11 贡献。

1.0.0 (2014-12-05)

  • 修复了使用预取时移除 select_related 的问题(#9)。

项目详情


下载文件

下载您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分布

django-prefetch-1.2.3.tar.gz (24.1 kB 查看散列

上传时间

构建分布

django_prefetch-1.2.3-py2.py3-none-any.whl (7.5 kB 查看散列

上传于 Python 2 Python 3

由以下机构支持