Skip to main content

Use SQL Join with Django ORM models having no relations.

Project description

django-join-unrelated

Python version Tests

Use SQL Join with Django ORM models having no relations.

If you have models in your project that share the same data but have no relations, you might face a situation when you need to join them. But Django does not provide this functionality yet.

With django-join-unrelated you can do the following (models defined here):

from app.core.models import Jedi, Person

Person.objects.create(first_name='Padme', last_name='Amidala', birth_place='Naboo')
Person.objects.create(first_name='Obi-Wan', last_name='Kenobi', birth_place='Stewjon')
Jedi.objects.create(first_name='Obi-Wan', last_name='Kenobi', force=100)
Jedi.objects.create(first_name='Mace', last_name='Windu', force=80)

Jedi.objects.join(first_name=Person.first_name).values_list('first_name')
# <UnrelatedJoinQuerySet [('Obi-Wan',)]>

print(Jedi.objects.join(first_name=Person.first_name).values_list('first_name').query)
# SELECT "core_jedi"."first_name" FROM "core_jedi" INNER JOIN core_person ON ("core_jedi"."first_name" = core_person."first_name")

# Set join type explicitly
from django_join_unrelated import JoinType

Jedi.objects.join(first_name=Person.first_name, join_type=JoinType.FULL)

# Join on multiple fields
Jedi.objects.join(first_name=Person.first_name, last_name=Person.last_name)

# Join multiple models
Jedi.objects.join(first_name=Person.first_name, id=User.id)

django-join-unrelated tries to keep all QuerySet power where it is possible:

Jedi.objects.join(first_name=Person.first_name).filter(last_name='Kenobi')
# <UnrelatedJoinQuerySet [<Jedi: Obi-Wan Kenobi>]>

Jedi.objects.join(first_name=Person.first_name).annotate(name=F('first_name'))[0].name
# 'Obi-Wan'

Jedi.objects.join(first_name=Person.first_name).aggregate(Sum('force'))
# {'force__sum': 100}

Installation

You can install django-join-unrelated using pip:

pip install django-join-unrelated

Usage

Just import UnrelatedJoinManager and set it as an attribute to your models:

from django.db import models
from django_join_unrelated import UnrelatedJoinManager

class Jedi(models.Model):
    first_name = models.CharField('First name', max_length=128)
    last_name = models.CharField('Last name', max_length=128)
    force = models.IntegerField('Force')

    objects = UnrelatedJoinManager()

    class Meta:
        verbose_name = 'Jedi'

Already implemented:

  • filtering via joins

Not implemented yet but planned:

  • unrelated objects selection
  • return of joined values

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-join-unrelated-0.2.0.tar.gz (5.5 kB view hashes)

Uploaded Source

Built Distribution

django_join_unrelated-0.2.0-py3-none-any.whl (5.6 kB view hashes)

Uploaded Python 3

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