Skip to main content

ORM extensions for performance-conscious perfectionists.

Project description

Latest version https://travis-ci.org/chrisseto/django-include.svg?branch=master

ORM extensions for performance-conscious perfectionists.

Django-include provides select_related functionality for Many-to-X relations.

Requirements

Python 2.7 or 3.5+, Django 1.9+, and any SQL server with support for JSON aggregations.

Currently tested against Postgres 9.6. May work with SQLite with the JSON1 extension.

Installation

pip install django-include

Usage

Add include to INSTALLED_APPS.

Attach IncludeManager to a model:

from include import IncludeManager

class BlogPost(models.Model):
    objects = IncludeManager()

Subclass IncludeQuerySet:

from include import IncludeQuerySet

class CustomQuerySet(IncludeQuerySet):
    def custom_method(self):
        pass

class BlogPost(models.Model):
    objects = CustomQuerySet.as_manager()

What/Why?

Consider the following:

Given the following models.

class Email(Model):
    name = CharField()
    user = ForeignKey('User')


class User(Model):
    emails = ...


class Contributor(Model):
    role = CharField()
    user = ForeignKey('User')
    project = ForeignKey('Project')

class Project(Model):
    contributors = ...

There is an endpoint that returns all the users that contributed to a project, their roles, and their email addresses.

If this endpoint were to be implemented using just Django’s ORM, it would end up looking something like this:

project = Project.objects.get(pk=id)  # 1 Query
for contributor in project.contributors.select_related('users'):  # 1 Query
    [x for x in contributor.user.emails.all()]  # N * M Queries!
    # Some serialization code

At first this solution seems fine, but what happens when a project has an entire college of people, each with a couple email addresses? Now, there are certainly other tricks that could be done here to reduce the number of queries and runtime. For instance, dropping down into raw SQL with a couple joins and/or subselects.

Or you could just use .include, do a single query, and not have to explain all the neat things you did.

project = Project.objects.include('contributors__user__emails')  # 1 Query
for contributor in project.contributors.all():  # Already loaded
    [x for x in contributor.user.emails.all()]  # Already loaded
    # Some serialization code

How?

Django Include abuses JSON aggregations and Django’s extra/annotate functions to embed related data.

License

MIT licensed. See the bundled LICENSE file for more details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-include-0.2.4.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

django_include-0.2.4-py2.py3-none-any.whl (10.8 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django-include-0.2.4.tar.gz.

File metadata

File hashes

Hashes for django-include-0.2.4.tar.gz
Algorithm Hash digest
SHA256 e64eddd3844bcf17085087ad1a8e6f8e88b9e676c5ee4e06c272b5fdb05a1ef1
MD5 8eacf096fe58b373712a5761cc7105a1
BLAKE2b-256 33e83e9f98b1a13ccf52a98ca19d4da6dfe53d14bd04acbf867e8d77cebb215b

See more details on using hashes here.

File details

Details for the file django_include-0.2.4-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_include-0.2.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 2ac4ca769c05d54c60d471b0f7d5ba749b9c62761ff86f4256b586c8701394a1
MD5 871183631874e062f0eb3cbe8947c253
BLAKE2b-256 4803d9020a08fe342ca5ce394968576e6f0ec73e05d3eba94a7675f3de26e27f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page