Skip to main content

Chain together multiple (disparate) QuerySets to treat them as a single QuerySet.

Project description

https://travis-ci.org/percipient/django-querysetsequence.svg?branch=master

The QuerySetSequence wrapper helps to deal with disparate QuerySet classes, while treating them as a single QuerySet.

Supported Features

Listed below are features of Django’s QuerySets that QuerySetSequence implements. The behavior should match that of QuerySet, but applied across multiple QuerySets:

  • Methods that take a list of fields (e.g. filter(), exclude(), get(), order_by()) must use fields that are common across all sub-QuerySets.

  • Relationships across related models work (e.g. 'foo__bar', 'foo', or 'foo_id'). syntax).

  • The sub-QuerySets are evaluated as late as possible (e.g. during iteration, slicing, pickling, repr()/len()/list()/bool() calls).

  • Public QuerySet API methods that are untested/unimplemented raise NotImplementedError. AttributeError is raised on attributes not explictly inherited from QuerySet.

QuerySet API implemented by QuerySetSequence

Method

Implemented?

Notes

filter()

exclude()

annotate()

order_by()

Does not support random order_by() (e.g. order_by('?'))

reverse()

distinct()

values()

values_list()

dates()

datetimes()

none()

all()

select_related()

prefetch_related()

extra()

defer()

only()

using()

select_for_update()

raw()

get()

create()

Cannot be implemented in QuerySetSequence.

get_or_create()

Cannot be implemented in QuerySetSequence.

update_or_create()

Cannot be implemented in QuerySetSequence.

bulk_create()

Cannot be implemented in QuerySetSequence.

count()

in_bulk()

Cannot be implemented in QuerySetSequence.

iterator()

latest()

earliest()

first()

last()

aggregate()

exists()

update()

Cannot be implemented in QuerySetSequence.

delete()

as_manager()

Requirements

  • Python (2.7)

  • Django (1.8, 1.9)

Support for Python (3.3, 3.4, 3.5) is wanted. If you wish an older version of Django to be supported, please submit a pull request.

Installation

Install the package using pip.

pip install --upgrade django-querysetsequence

Usage

# Import QuerySetSequence
from queryset_sequence import QuerySetSequence

# Create QuerySets you want to chain.
from .models import SomeModel, OtherModel

# Chain them together.
query = QuerySetSequence(SomeModel.objects.all(), OtherModel.objects.all())

# Use query as if it were a QuerySet! E.g. in a ListView.

Example

class Author(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        ordering = ['name']

    def __str__(self):
        return self.name


class Article(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author)

    def __str__(self):
        return "%s by %s" % (self.title, self.author)


class Book(models.Model):
    title = models.CharField(max_length=50)
    author = models.ForeignKey(Author)
    release = models.DateField(auto_now_add=True)

    def __str__(self):
        return "%s by %s" % (self.title, self.author)

# Create some data.
alice = Author.objects.create(name='Alice')
article = Article.objects.create(title='Dancing with Django', author=alice)

bob = Author.objects.create(name='Bob')
article = Article.objects.create(title='Django-isms', author=bob)
article = Book.objects.create(title='Biography', author=bob)

# Create some QuerySets.
books = Book.objects.all()
articles = Article.objects.all()

# Combine them into a single iterable.
published_works = QuerySetSequence(books, articles)

# Find Bob's titles.
bob_works = published_works.filter(author=bob)
# Still an iterable.
print([w.title for w in bob_works])  # prints: ['Biography', 'Django-isms']

# Alphabetize the QuerySet.
published_works = published_works.order_by('title')
print([w.title for w in published_works])  # prints ['Biography', 'Dancing with Django', 'Django-isms']

Attribution

This is based on a few DjangoSnippets that had been going around:

Contribute

  • Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.

  • Fork the repository on GitHub to start making your changes.

  • Write a test which shows that the bug was fixed or that the feature works as expected.

  • Send a pull request and bug the maintainer until it gets merged and published.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

django_querysetsequence-0.3-py2.py3-none-any.whl (13.7 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django_querysetsequence-0.3-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_querysetsequence-0.3-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 9a4fee876867318294f3fb16f38f929e2c1b60cd4512c4cd592f9762b76b901c
MD5 c4c43a78f8548253b8fe5112c7f6ad20
BLAKE2b-256 dc5108f62f0fc5aa8d8065ef686004a9588b3003a20cc5a55819f5c0790d4a09

See more details on using hashes here.

Provenance

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