Skip to main content

Make efficient and explicit SQL queries with the Django ORM automatically

Project description

django-orm-plus

PyPI version Python versions

A collection of useful ORM features to make using the Django ORM convenient, performant and safe

Installation

pip install django-orm-plus

Then add django_orm_plus to INSTALLED_APPS

Now you must do one of the following:

  1. Set AUTO_ADD_MODEL_MIXIN to True in settings.py:

    DJANGO_ORM_PLUS = {
        "AUTO_ADD_MODEL_MIXIN": True,
    }
    

    This will automatically patch your models with ORMPlusModelMixin

  2. Or, add the following model mixin to your models manually:

    from django.db import models
    from django_orm_plus.mixins import ORMPlusModelMixin
    
    
    class MyModel(models.Model, ORMPlusModelMixin):
        name = models.CharField(max_length=10)
    

Usage

This library has three important functions for use on Django QuerySets:

  • .strict()
  • .fetch_related()
  • .bulk_update_or_create()

strict

Strict mode makes sure your ORM queries are efficient and safe by not allowing related objects to be loaded lazily, therefore select_related or prefetch_related must be used if related objects are needed. This avoids the n+1 query problem.

Strict mode will also raise an error when a deferred field (.defer() or .only()) is accessed.

You only need to add .strict() on your queryset wherever it's being used. So for example in a DRF view:

class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all().strict()
    serializer_class = UserSerializer
    permission_classes = [IsAdminUser]

Now your queryset is strict-mode enabled and your view will error if any relations are loaded for the user queryset eg. users[0].profile will error if profile is a foreign key. To fix, change the query to also fetch the relation using either select_related or prefetch_related:

queryset = User.objects.all().select_related("profile").strict()

fetch_related

Combines both select_related and prefetch_related to reduce the total number of queries for you automatically.

So instead of:

queryset = (
    User.objects.all()
    .select_related("profile")
    .prefetch_related(
        "likes",
        Prefetch("books", queryset=Book.objects.all().select_related("author")),
    )
)

It's now simply:

queryset = User.objects.all().fetch_related("profile", "likes", "books__author")

Of course, the two methods can be used together to get easy and safe queryset evaluation:

queryset = User.objects.all().fetch_related("profile", "likes", "books__author").strict()

Since select_related does a join in SQL, fetch_related opts to use select_related when possible, and in other cases will use prefetch_related which adds a single additional query and does the join in Python.

bulk_update_or_create

updated, created = User.objects.bulk_update_or_create(
    [User(username="john123", first_name="Jonny"), User(username="jane_doe", first_name="Alexa")],
    lookup_fields=["username"],
    update_fields=["first_name"],
)

This will combine bulk_update and bulk_create and return the records that were updated and created. lookup_fields is a list of field names that should uniquely identify a record. This method takes batch_size as an optional parameter which defaults to 1000

Configuration

You can set the following configuration object in settings.py:

DJANGO_ORM_PLUS = {
    "AUTO_ADD_MODEL_MIXIN": False,
    "STRICT_MODE_GLOBAL_OVERRIDE": None,
}

AUTO_ADD_MODEL_MIXIN is a boolean flag that will auto-patch all the models on load with ORMPlusModelMixin

STRICT_MODE_GLOBAL_OVERRIDE is a boolean flag that will enable or disable strict mode without considering if .strict() is used. This can be useful if you want to disable strict mode on production, or have all querysets use strict mode for local development.

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-orm-plus-0.1.0b4.tar.gz (22.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_orm_plus-0.1.0b4-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

Details for the file django-orm-plus-0.1.0b4.tar.gz.

File metadata

  • Download URL: django-orm-plus-0.1.0b4.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.5

File hashes

Hashes for django-orm-plus-0.1.0b4.tar.gz
Algorithm Hash digest
SHA256 99c30096d332aef050cad46c3d3255d0432af23b7dbea0cd7dc499a46ba9db27
MD5 badadbcec14190b131ed7ee1eba90c8c
BLAKE2b-256 ad01471b5ac290f2d5caf6396f21659a1aee5535e698302038ab67f741b87d1f

See more details on using hashes here.

File details

Details for the file django_orm_plus-0.1.0b4-py3-none-any.whl.

File metadata

  • Download URL: django_orm_plus-0.1.0b4-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.5

File hashes

Hashes for django_orm_plus-0.1.0b4-py3-none-any.whl
Algorithm Hash digest
SHA256 2352ea5efd56843bbe949c4d2fac45ee69a93615b76b15c99207dddb035b27ed
MD5 f6bef99530ebf5090a94e3b4e0ccca0c
BLAKE2b-256 8a806dcd2bc40fd1942a71ff2dfe6eafae092018314f1d795d0ab7401568a486

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