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

Uploaded Source

Built Distribution

django_include-0.2.2-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.2.tar.gz.

File metadata

File hashes

Hashes for django-include-0.2.2.tar.gz
Algorithm Hash digest
SHA256 4eecd3d81b130cc6ada69fc25c11b287c75dac9790b050f495c9a7ec61999940
MD5 664d0afd9b57c489076d021c362a9c63
BLAKE2b-256 f931b7b4422f85a86b16e323c0b83aa1899d79d82ad0c1349c0447236d3d5a85

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_include-0.2.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 5138554f18a24d5d67905e93c1be6b2f101b937271530e51b283452fb0d7a626
MD5 7474648bbf17ff3797eba8d311540d71
BLAKE2b-256 e9b25882bf7fd466843d5ac00b0cb79a12cd39d86bdbeccbcecfe66090e6f6e2

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