django-polymodels
A django application that provides a simple way to retrieve models type casted to their original ContentType.
Installation
>>> pip install django-polymodels
Make sure 'django.contrib.contenttypes' and 'polymodels' are in your INSTALLED_APPS
INSTALLED_APPS += ('django.contrib.contenttypes', 'polymodels')
Usage
Subclass PolymorphicModel, an abstract model class.
from django.db import models
from polymodels.models import PolymorphicModel
class Animal(PolymorphicModel):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Mammal(Animal):
pass
class Dog(Mammal):
pass
class Reptile(Animal):
pass
class Snake(Reptile):
class Meta:
proxy = True
Objects are created the same way as usual and their associated ContentType is saved automatically:
>>> animal = Animal.objects.create(name='animal') >>> mammal = Mammal.objects.create(name='mammal') >>> reptile = Reptile.objects.create(name='reptile') >>> snake = Snake.objects.create(name='snake')
To retreive type casted instances from the Animal.objects manager you just have to use the select_subclasses method.
>>> Animal.objects.select_subclasses() [<Animal: animal>, <Mammal: mammal>, <Reptile: reptile>, <Snake: snake>]
You can also retreive a subset of the subclasses by passing them as arguments to select_subclass.
>>> Animal.objects.select_subclasses(Reptile) [<Reptile: reptile>, <Snake: snake>]
Or directly from subclasses managers.
>>> Reptile.objects.select_subclasses(Snake) [<Snake: snake>]
Note that you can also retrieve original results by avoiding the select_subclasses call.
>>> Animal.objects.all() [<Animal: animal>, <Animal: mammal>, <Animal: reptile>, <Animal: snake>]
It’s also possible to select only instances of the model to which the manager is attached by using the exclude_subclasses method.
>>> Mammal.objects.all() [<Mammal: mammal>]
Each instance of PolymorphicModel has a type_cast method that knows how to convert itself to the correct ContentType.
>>> animal_snake = Animal.objects.get(pk=snake.pk) <Animal: snake> >>> animal_snake.type_cast() <Snake: snake> >>> animal_snake.type_cast(Reptile) <Reptile: snake>
If the PolymorphicModel.content_type fields conflicts with one of your existing fields you just have to subclass polymodels.models.BasePolymorphicModel and specify which field polymodels should use instead by defining a CONTENT_TYPE_FIELD attribute on your model. This field must be a ForeignKey to ContentType.
from django.contrib.contenttypes.models import ContentType
from django.db import models
from polymodels.models import BasePolymorphicModel
class MyModel(BasePolymorphicModel):
CONTENT_TYPE_FIELD = 'polymorphic_ct'
polymorphic_ct = models.ForeignKey(ContentType)
How it works
Under the hood select_subclasses calls seleted_related to avoid unnecessary queries and filter if you pass some classes to it. On queryset iteration, the fetched instanced are converted to their correct type by calling BasePolymorphicModel.type_cast. Note that those lookups are cached on class creation to avoid computing them on every single query.
Contribute
If you happen to encounter a bug or would like to suggest a feature addition please file an issue or create a pull request containing tests.
Credits
Inspired by a post of Jeff Elmores.
Metadata
Release files for django-polymodels 1.8.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| django_polymodels-1.8.1.tar.gz | 14.6 kB | Without provenance | Details for django_polymodels-1.8.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| django_polymodels-1.8.1-py2.py3-none-any.whl | Python 3, Python 2 | none | any | Details for django_polymodels-1.8.1-py2.py3-none-any.whl |
Total release size: 25.8 kB
Release files / django_polymodels-1.8.1.tar.gz
| Download URL | django_polymodels-1.8.1.tar.gz |
|---|---|
| Size | 14.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb2956192fe13bbd0f32f05f76d6b688d045cbb2ece76c40fff06926d6b3f497
|
|
BLAKE2b-256 checksum How to use checksums |
4881c93c602b2c65830d00ab13cf5540026df3213d38dd79cc4bf82c27595762
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.21
|
Release files / django_polymodels-1.8.1-py2.py3-none-any.whl
| Download URL | django_polymodels-1.8.1-py2.py3-none-any.whl |
|---|---|
| Size | 11.2 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
4fc16ac535a87fd9b3f6e7ccf7f9da509978d024f36da59ed250dbb6bf11fa75
|
|
BLAKE2b-256 checksum How to use checksums |
67815bd124652083ebcd38bd7cfa38d0dfb20aee55b0559f95847dfbef8036b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.21
|
Security for django-polymodels 1.8.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.