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

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_include-0.2.0-py2.py3-none-any.whl (10.6 kB view details)

Uploaded Python 2Python 3

File details

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

File metadata

File hashes

Hashes for django-include-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6a291999c8168a983f4d2c787b04e8763ee254733cc8f278aa43fd7d08cfe551
MD5 da986171b65dcbb5a5fc9d60f422b2fd
BLAKE2b-256 fb322121c6293126c5f9164494c2661dc6d63114f152677c42575ad3c3fd04f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_include-0.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 b288d6b7534df6acbe1806b0ac5548662392570ddab0381b58b7b60db5a02d97
MD5 40aed4c2528b988d68008df512d30f22
BLAKE2b-256 fd362ee7225fc4688a7e665195de12c8fd974cefcfc785d917e046df0a7b063f

See more details on using hashes here.

Supported by

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