Allows ORM constructs to be sealed to prevent them from executing queries on attribute accesses.
Project description
Django application providing queryset sealing capability to force appropriate usage of only()/defer() and select_related()/prefetch_related().
Installation
pip install django-seal
Usage
# models.py
from django.db import models
from seal.models import SealableModel
class Location(SealableModel):
latitude = models.FloatField()
longitude = models.FloatField()
class SeaLion(SealableModel):
height = models.PositiveIntegerField()
weight = models.PositiveIntegerField()
location = models.ForeignKey(Location, models.CASCADE, null=True)
previous_locations = models.ManyToManyField(Location, related_name='previous_visitors')
By default UnsealedAttributeAccess warnings will be raised on sealed objects attributes accesses
>>> location = Location.objects.create(latitude=51.585474, longitude=156.634331)
>>> sealion = SeaLion.objects.create(height=1, weight=100, location=location)
>>> sealion.previous_locations.add(location)
>>> SeaLion.objects.only('height').seal().get().weight
UnsealedAttributeAccess:: Attempt to fetch deferred field "weight" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().location
UnsealedAttributeAccess: Attempt to fetch related field "location" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().previous_locations.all()
UnsealedAttributeAccess: Attempt to fetch many-to-many field "previous_locations" on sealed <SeaLion instance>.
You can elevate the warnings to exceptions by filtering them. This is useful to assert no unsealed attribute accesses are performed when running your test suite for example.
>>> import warnings
>>> from seal.exceptions import UnsealedAttributeAccess
>>> warnings.filterwarnings('error', category=UnsealedAttributeAccess)
>>> SeaLion.objects.only('height').seal().get().weight
Traceback (most recent call last)
...
UnsealedAttributeAccess:: Attempt to fetch deferred field "weight" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().location
Traceback (most recent call last)
...
UnsealedAttributeAccess: Attempt to fetch related field "location" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().previous_locations.all()
Traceback (most recent call last)
...
UnsealedAttributeAccess: Attempt to fetch many-to-many field "previous_locations" on sealed <SeaLion instance>.
Or you can configure logging to capture warnings to log unsealed attribute accesses to the py.warnings logger which is a nice way to identify and address unsealed attributes accesses from production logs without taking your application down if some instances happen to slip through your battery of tests.
>>> import logging
>>> logging.captureWarnings(True)
Sealable managers can also be automatically sealed at model definition time to avoid having to call seal() systematically by passing seal=True to SealableModel subclasses, SealableManager and SealableQuerySet.as_manager.
from django.db import models
from seal.models import SealableManager, SealableModel, SealableQuerySet
class Location(SealableModel, seal=True):
latitude = models.FloatField()
longitude = models.FloatField()
class SeaLion(SealableModel):
height = models.PositiveIntegerField()
weight = models.PositiveIntegerField()
location = models.ForeignKey(Location, models.CASCADE, null=True)
previous_locations = models.ManyToManyField(Location, related_name='previous_visitors')
objects = SealableManager(seal=True)
others = SealableQuerySet.as_manager(seal=True)
Development
Make your changes, and then run tests via tox:
tox
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django_seal-1.6.2.tar.gz
.
File metadata
- Download URL: django_seal-1.6.2.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.0 CPython/3.12.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e58e076cb2aeb3939092b9fb14dc89d9ffddcc06f26d245786a90f86bd5514e2 |
|
MD5 | 8da36c099be1578548493cd28ed8704e |
|
BLAKE2b-256 | 8cc0a46d21f786cf956f7895fbdb8e50ede6e2a0944116f7ade2b542339ea58b |
File details
Details for the file django_seal-1.6.2-py2.py3-none-any.whl
.
File metadata
- Download URL: django_seal-1.6.2-py2.py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.0 CPython/3.12.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 13ba7fea1346ed69f47ff84afd449e03749c6b3daf54f34dd6eaabf87efa1663 |
|
MD5 | d7f12f9b67f307043af9e3a4e18e44ba |
|
BLAKE2b-256 | ba815e2c7283b0516b67b09feaed3e662530132e869a8168003acc533068ca48 |