Skip to main content

ORM extensions for performance-conscious perfectionists.

Project description

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.3.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

django_include-0.2.3-py2.py3-none-any.whl (10.7 kB view details)

Uploaded Python 2 Python 3

File details

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

File metadata

File hashes

Hashes for django-include-0.2.3.tar.gz
Algorithm Hash digest
SHA256 96d386c30e514367b5de2df8bf26ac70fa9fae13b556a2275192e7ab24ae29ba
MD5 272dea71bb1a0f54d508c08e96b69a51
BLAKE2b-256 42328ea503025f759fff69e226e8580437c68165b16a0209b6acda21855ecd22

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_include-0.2.3-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 3c7d81870d68775a4977b4596f495a14cd97a1dd699cb15fdcb81a3715c35a88
MD5 ea46f8086efe58e22603516fc6922e4c
BLAKE2b-256 3f9434ec0a44eebcdc36823a40a2949bf2ab132531690a5826771356c736aaea

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