# Django STI Models
An improved implementation of Single Table Inheritance (STI) for Django with better monkey patching, type safety, and performance.
## Features
- **Improved Monkey Patching**: Cleaner metaclass implementation that's more maintainable and less prone to conflicts
- **Type Safety**: Full type hints and validation throughout the codebase
- **Better Performance**: Optimized type registration and lookup mechanisms with caching
- **Enhanced Error Handling**: Comprehensive exception handling with meaningful error messages
- **Cleaner API**: More intuitive interface for working with typed models
- **Validation**: Built-in validation for type registration and field configuration
- **Django Admin Integration**: Seamless admin interface with type-aware filtering and forms
- **Management Commands**: Built-in commands for validation and maintenance
- **Advanced Utilities**: Comprehensive utility functions for common operations
- **Type Statistics**: Built-in support for analyzing type distribution
## Installation
```bash
# Using Poetry (recommended)
poetry add django-sti-models
# Using pip
pip install django-sti-models
```
**Requirements:**
- Django >= 4.2, < 6.0
- Python >= 3.8
## Quick Start
### 1. Define Your Base Model
```python
from django_sti_models import TypedModel, TypeField
class Animal(TypedModel):
name = models.CharField(max_length=100)
age = models.IntegerField()
animal_type = TypeField() # Use descriptive field names!
class Meta:
abstract = True
```
### 2. Create Your Subtypes
```python
class Dog(Animal):
breed = models.CharField(max_length=50)
def bark(self):
return f"{self.name} says woof!"
class Cat(Animal):
color = models.CharField(max_length=30)
def meow(self):
return f"{self.name} says meow!"
class Bird(Animal):
wingspan = models.FloatField()
def fly(self):
return f"{self.name} is flying!"
```
### 3. Use Your Typed Models
```python
# Create instances
dog = Dog.objects.create(name="Rex", age=3, breed="Golden Retriever")
cat = Cat.objects.create(name="Whiskers", age=2, color="Orange")
bird = Bird.objects.create(name="Tweety", age=1, wingspan=12.5)
# Query by type
dogs = Dog.objects.all() # Only returns Dog instances
cats = Cat.objects.all() # Only returns Cat instances
# Query all animals
all_animals = Animal.objects.all() # Returns all types
# Get the real instance type
animal = Animal.objects.first()
real_animal = animal.get_real_instance() # Returns the correct subtype
# Check available types
available_types = Animal.get_all_types()
# Returns: {'Dog': <class 'Dog'>, 'Cat': <class 'Cat'>, 'Bird': <class 'Bird'>}
```
## Advanced Usage
### Custom Type Field Names
You can use a custom field name for the type field:
```python
class Vehicle(TypedModel):
name = models.CharField(max_length=100)
vehicle_kind = TypeField() # Custom field name
class Meta:
abstract = True
class Car(Vehicle):
doors = models.IntegerField()
class Motorcycle(Vehicle):
engine_size = models.FloatField()
```
### Django Admin Integration
The package provides seamless Django admin integration:
```python
from django_sti_models import TypedModelAdmin, register_typed_models
# Option 1: Automatic registration
register_typed_models(Vehicle)
# Option 2: Custom admin class
class VehicleAdmin(TypedModelAdmin):
list_display = ['name', 'vehicle_kind', 'created_at']
list_filter = ['vehicle_kind']
search_fields = ['name']
# Register with admin
admin.site.register(Vehicle, VehicleAdmin)
```
### Management Commands
Use built-in management commands for validation and maintenance:
```bash
# Validate all STI models
python manage.py validate_sti_models
# Validate specific app
python manage.py validate_sti_models --app myapp
# Show type statistics
python manage.py validate_sti_models --stats
# Validate specific model
python manage.py validate_sti_models --model Vehicle
```
### Advanced Utility Functions
```python
from django_sti_models.utils import (
get_typed_queryset,
create_typed_instance,
get_type_hierarchy,
get_type_statistics,
filter_by_type,
validate_type_consistency,
migrate_type_field
)
# Get queryset filtered by specific types
land_vehicles = get_typed_queryset(Vehicle, ['Car', 'Motorcycle'])
# Create instance by type name
car = create_typed_instance(Vehicle, 'Car', name='Tesla', doors=4)
# Get type hierarchy
hierarchy = get_type_hierarchy(Vehicle)
# Get type statistics
stats = get_type_statistics(Vehicle)
# Returns: {'Car': 10, 'Motorcycle': 5}
# Filter existing queryset by type
cars_only = filter_by_type(Vehicle.objects.all(), 'Car')
# Validate type consistency
errors = validate_type_consistency(Vehicle)
# Migrate type field data
updated_count = migrate_type_field(Vehicle, 'old_type', 'new_type')
```
### Type Validation
The package includes comprehensive validation:
```python
from django_sti_models.utils import validate_type_registration
# Validate your type registration
errors = validate_type_registration(Vehicle)
if errors:
print("Validation errors:", errors)
```
## Field Naming Best Practices
**✅ Good field names:**
- `animal_type` (for Animal models)
- `content_type` (for Content models)
- `vehicle_kind` (for Vehicle models)
- `user_role` (for User models)
- `product_category` (for Product models)
**❌ Avoid these:**
- `type` (Python reserved word)
- `kind` (too generic)
- `category` (too generic)
**Benefits of descriptive names:**
- Clearer code intent
- Better IDE support
- Avoids Python reserved word conflicts
- More maintainable code
## Improvements Over Original
### 1. Better Monkey Patching
The original django-typed-models used aggressive monkey patching that could conflict with other Django apps. This implementation:
- Uses a cleaner metaclass approach
- Minimizes interference with Django's internals
- Provides better error handling for conflicts
- Is more maintainable and debuggable
### 2. Enhanced Type Safety
- Full type hints throughout the codebase
- Better validation of type registration
- Improved error messages for debugging
- Type-safe manager implementations
- Generic type support
### 3. Performance Optimizations
- More efficient type registration
- Optimized queryset filtering
- Reduced memory usage
- Better caching of type information
- LRU caching for frequently accessed data
### 4. Cleaner API
- More intuitive method names
- Better separation of concerns
- Comprehensive utility functions
- Improved documentation
- Enhanced manager methods (get_or_create, update_or_create)
### 5. Django Admin Integration
- Seamless admin interface
- Type-aware filtering and forms
- Automatic type field handling
- Validation tools
- Statistics display
### 6. Management Commands
- Built-in validation commands
- Type consistency checking
- Statistics reporting
- Maintenance utilities
## Configuration
### Django Settings
Add to your `settings.py`:
```python
INSTALLED_APPS = [
# ... other apps
'django_sti_models',
]
```
### Type Field Configuration
The `TypeField` supports various configuration options:
```python
class MyModel(TypedModel):
# Basic usage
model_type = TypeField()
# With custom configuration
model_type = TypeField(
max_length=50,
db_index=True,
editable=False
)
```
### Admin Configuration
```python
# In your admin.py
from django_sti_models import TypedModelAdmin, register_typed_models
# For automatic registration
register_typed_models(YourBaseModel)
# For custom admin
class YourModelAdmin(TypedModelAdmin):
list_display = ['name', 'model_type', 'created_at']
list_filter = ['model_type']
readonly_fields = ['model_type']
```
## Testing
```bash
# Run tests
poetry run pytest
# Run with coverage
poetry run pytest --cov=django_sti_models
# Run type checking
poetry run mypy django_sti_models/
# Run validation
python manage.py validate_sti_models
```
## Best Practices
### 1. Use Descriptive Type Field Names
```python
# Good
class Content(TypedModel):
content_type = TypeField()
# Also good
class Vehicle(TypedModel):
vehicle_kind = TypeField()
```
### 2. Implement Polymorphic Methods
```python
class Animal(TypedModel):
def make_sound(self):
raise NotImplementedError
class Dog(Animal):
def make_sound(self):
return "Woof!"
class Cat(Animal):
def make_sound(self):
return "Meow!"
```
### 3. Validate Type Consistency
```python
# Regular validation
from django_sti_models.utils import validate_type_consistency
errors = validate_type_consistency(Animal)
# Using management command
python manage.py validate_sti_models --app animals
```
### 4. Use Type-Aware Queries
```python
# Query specific types directly
dogs = Dog.objects.all()
# Use utility functions for complex filtering
land_animals = filter_by_type(Animal.objects.all(), ['Dog', 'Cat'])
```
### 5. Leverage Admin Integration
```python
# Automatic registration
register_typed_models(Animal)
# Custom admin with type-aware features
class AnimalAdmin(TypedModelAdmin):
list_display = ['name', 'animal_type', 'age']
list_filter = ['animal_type']
```
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Run the test suite
6. Submit a pull request
## License
MIT License - see LICENSE file for details.
## Acknowledgments
This project is inspired by and improves upon the original [django-typed-models](https://github.com/craigds/django-typed-models) by Craig de Stigter.
Raw data
{
"_id": null,
"home_page": null,
"name": "django-sti-models",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0.0,>=3.8.1",
"maintainer_email": null,
"keywords": "django, sti, single-table-inheritance, models, polymorphic, admin",
"author": "Konrad Beck",
"author_email": "konrad.beck@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/53/fc/aec0d148c0b824652584ca71f9568ebb69cf083065ea9843f45f109074e2/django_sti_models-0.1.14.tar.gz",
"platform": null,
"description": "# Django STI Models\n\nAn improved implementation of Single Table Inheritance (STI) for Django with better monkey patching, type safety, and performance.\n\n## Features\n\n- **Improved Monkey Patching**: Cleaner metaclass implementation that's more maintainable and less prone to conflicts\n- **Type Safety**: Full type hints and validation throughout the codebase\n- **Better Performance**: Optimized type registration and lookup mechanisms with caching\n- **Enhanced Error Handling**: Comprehensive exception handling with meaningful error messages\n- **Cleaner API**: More intuitive interface for working with typed models\n- **Validation**: Built-in validation for type registration and field configuration\n- **Django Admin Integration**: Seamless admin interface with type-aware filtering and forms\n- **Management Commands**: Built-in commands for validation and maintenance\n- **Advanced Utilities**: Comprehensive utility functions for common operations\n- **Type Statistics**: Built-in support for analyzing type distribution\n\n## Installation\n\n```bash\n# Using Poetry (recommended)\npoetry add django-sti-models\n\n# Using pip\npip install django-sti-models\n```\n\n**Requirements:**\n- Django >= 4.2, < 6.0\n- Python >= 3.8\n\n## Quick Start\n\n### 1. Define Your Base Model\n\n```python\nfrom django_sti_models import TypedModel, TypeField\n\nclass Animal(TypedModel):\n name = models.CharField(max_length=100)\n age = models.IntegerField()\n animal_type = TypeField() # Use descriptive field names!\n \n class Meta:\n abstract = True\n```\n\n### 2. Create Your Subtypes\n\n```python\nclass Dog(Animal):\n breed = models.CharField(max_length=50)\n \n def bark(self):\n return f\"{self.name} says woof!\"\n\nclass Cat(Animal):\n color = models.CharField(max_length=30)\n \n def meow(self):\n return f\"{self.name} says meow!\"\n\nclass Bird(Animal):\n wingspan = models.FloatField()\n \n def fly(self):\n return f\"{self.name} is flying!\"\n```\n\n### 3. Use Your Typed Models\n\n```python\n# Create instances\ndog = Dog.objects.create(name=\"Rex\", age=3, breed=\"Golden Retriever\")\ncat = Cat.objects.create(name=\"Whiskers\", age=2, color=\"Orange\")\nbird = Bird.objects.create(name=\"Tweety\", age=1, wingspan=12.5)\n\n# Query by type\ndogs = Dog.objects.all() # Only returns Dog instances\ncats = Cat.objects.all() # Only returns Cat instances\n\n# Query all animals\nall_animals = Animal.objects.all() # Returns all types\n\n# Get the real instance type\nanimal = Animal.objects.first()\nreal_animal = animal.get_real_instance() # Returns the correct subtype\n\n# Check available types\navailable_types = Animal.get_all_types()\n# Returns: {'Dog': <class 'Dog'>, 'Cat': <class 'Cat'>, 'Bird': <class 'Bird'>}\n```\n\n## Advanced Usage\n\n### Custom Type Field Names\n\nYou can use a custom field name for the type field:\n\n```python\nclass Vehicle(TypedModel):\n name = models.CharField(max_length=100)\n vehicle_kind = TypeField() # Custom field name\n \n class Meta:\n abstract = True\n\nclass Car(Vehicle):\n doors = models.IntegerField()\n\nclass Motorcycle(Vehicle):\n engine_size = models.FloatField()\n```\n\n### Django Admin Integration\n\nThe package provides seamless Django admin integration:\n\n```python\nfrom django_sti_models import TypedModelAdmin, register_typed_models\n\n# Option 1: Automatic registration\nregister_typed_models(Vehicle)\n\n# Option 2: Custom admin class\nclass VehicleAdmin(TypedModelAdmin):\n list_display = ['name', 'vehicle_kind', 'created_at']\n list_filter = ['vehicle_kind']\n search_fields = ['name']\n\n# Register with admin\nadmin.site.register(Vehicle, VehicleAdmin)\n```\n\n### Management Commands\n\nUse built-in management commands for validation and maintenance:\n\n```bash\n# Validate all STI models\npython manage.py validate_sti_models\n\n# Validate specific app\npython manage.py validate_sti_models --app myapp\n\n# Show type statistics\npython manage.py validate_sti_models --stats\n\n# Validate specific model\npython manage.py validate_sti_models --model Vehicle\n```\n\n### Advanced Utility Functions\n\n```python\nfrom django_sti_models.utils import (\n get_typed_queryset,\n create_typed_instance,\n get_type_hierarchy,\n get_type_statistics,\n filter_by_type,\n validate_type_consistency,\n migrate_type_field\n)\n\n# Get queryset filtered by specific types\nland_vehicles = get_typed_queryset(Vehicle, ['Car', 'Motorcycle'])\n\n# Create instance by type name\ncar = create_typed_instance(Vehicle, 'Car', name='Tesla', doors=4)\n\n# Get type hierarchy\nhierarchy = get_type_hierarchy(Vehicle)\n\n# Get type statistics\nstats = get_type_statistics(Vehicle)\n# Returns: {'Car': 10, 'Motorcycle': 5}\n\n# Filter existing queryset by type\ncars_only = filter_by_type(Vehicle.objects.all(), 'Car')\n\n# Validate type consistency\nerrors = validate_type_consistency(Vehicle)\n\n# Migrate type field data\nupdated_count = migrate_type_field(Vehicle, 'old_type', 'new_type')\n```\n\n### Type Validation\n\nThe package includes comprehensive validation:\n\n```python\nfrom django_sti_models.utils import validate_type_registration\n\n# Validate your type registration\nerrors = validate_type_registration(Vehicle)\nif errors:\n print(\"Validation errors:\", errors)\n```\n\n## Field Naming Best Practices\n\n**\u2705 Good field names:**\n- `animal_type` (for Animal models)\n- `content_type` (for Content models)\n- `vehicle_kind` (for Vehicle models)\n- `user_role` (for User models)\n- `product_category` (for Product models)\n\n**\u274c Avoid these:**\n- `type` (Python reserved word)\n- `kind` (too generic)\n- `category` (too generic)\n\n**Benefits of descriptive names:**\n- Clearer code intent\n- Better IDE support\n- Avoids Python reserved word conflicts\n- More maintainable code\n\n## Improvements Over Original\n\n### 1. Better Monkey Patching\n\nThe original django-typed-models used aggressive monkey patching that could conflict with other Django apps. This implementation:\n\n- Uses a cleaner metaclass approach\n- Minimizes interference with Django's internals\n- Provides better error handling for conflicts\n- Is more maintainable and debuggable\n\n### 2. Enhanced Type Safety\n\n- Full type hints throughout the codebase\n- Better validation of type registration\n- Improved error messages for debugging\n- Type-safe manager implementations\n- Generic type support\n\n### 3. Performance Optimizations\n\n- More efficient type registration\n- Optimized queryset filtering\n- Reduced memory usage\n- Better caching of type information\n- LRU caching for frequently accessed data\n\n### 4. Cleaner API\n\n- More intuitive method names\n- Better separation of concerns\n- Comprehensive utility functions\n- Improved documentation\n- Enhanced manager methods (get_or_create, update_or_create)\n\n### 5. Django Admin Integration\n\n- Seamless admin interface\n- Type-aware filtering and forms\n- Automatic type field handling\n- Validation tools\n- Statistics display\n\n### 6. Management Commands\n\n- Built-in validation commands\n- Type consistency checking\n- Statistics reporting\n- Maintenance utilities\n\n## Configuration\n\n### Django Settings\n\nAdd to your `settings.py`:\n\n```python\nINSTALLED_APPS = [\n # ... other apps\n 'django_sti_models',\n]\n```\n\n### Type Field Configuration\n\nThe `TypeField` supports various configuration options:\n\n```python\nclass MyModel(TypedModel):\n # Basic usage\n model_type = TypeField()\n \n # With custom configuration\n model_type = TypeField(\n max_length=50,\n db_index=True,\n editable=False\n )\n```\n\n### Admin Configuration\n\n```python\n# In your admin.py\nfrom django_sti_models import TypedModelAdmin, register_typed_models\n\n# For automatic registration\nregister_typed_models(YourBaseModel)\n\n# For custom admin\nclass YourModelAdmin(TypedModelAdmin):\n list_display = ['name', 'model_type', 'created_at']\n list_filter = ['model_type']\n readonly_fields = ['model_type']\n```\n\n## Testing\n\n```bash\n# Run tests\npoetry run pytest\n\n# Run with coverage\npoetry run pytest --cov=django_sti_models\n\n# Run type checking\npoetry run mypy django_sti_models/\n\n# Run validation\npython manage.py validate_sti_models\n```\n\n## Best Practices\n\n### 1. Use Descriptive Type Field Names\n```python\n# Good\nclass Content(TypedModel):\n content_type = TypeField()\n\n# Also good\nclass Vehicle(TypedModel):\n vehicle_kind = TypeField()\n```\n\n### 2. Implement Polymorphic Methods\n```python\nclass Animal(TypedModel):\n def make_sound(self):\n raise NotImplementedError\n\nclass Dog(Animal):\n def make_sound(self):\n return \"Woof!\"\n\nclass Cat(Animal):\n def make_sound(self):\n return \"Meow!\"\n```\n\n### 3. Validate Type Consistency\n```python\n# Regular validation\nfrom django_sti_models.utils import validate_type_consistency\nerrors = validate_type_consistency(Animal)\n\n# Using management command\npython manage.py validate_sti_models --app animals\n```\n\n### 4. Use Type-Aware Queries\n```python\n# Query specific types directly\ndogs = Dog.objects.all()\n\n# Use utility functions for complex filtering\nland_animals = filter_by_type(Animal.objects.all(), ['Dog', 'Cat'])\n```\n\n### 5. Leverage Admin Integration\n```python\n# Automatic registration\nregister_typed_models(Animal)\n\n# Custom admin with type-aware features\nclass AnimalAdmin(TypedModelAdmin):\n list_display = ['name', 'animal_type', 'age']\n list_filter = ['animal_type']\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests for new functionality\n5. Run the test suite\n6. Submit a pull request\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Acknowledgments\n\nThis project is inspired by and improves upon the original [django-typed-models](https://github.com/craigds/django-typed-models) by Craig de Stigter. ",
"bugtrack_url": null,
"license": null,
"summary": "Improved Django Single Table Inheritance (STI) models with admin integration and advanced utilities",
"version": "0.1.14",
"project_urls": null,
"split_keywords": [
"django",
" sti",
" single-table-inheritance",
" models",
" polymorphic",
" admin"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "21135de596a71246ada3ed0df2b003e544fc5a5b97ba372fe1deea21163ba5eb",
"md5": "19384a47918d30f56d8ceacf0b39504d",
"sha256": "a613bc676833abd824da7264cc39a65d7692020ebca3bc7d20ec790c7a4db064"
},
"downloads": -1,
"filename": "django_sti_models-0.1.14-py3-none-any.whl",
"has_sig": false,
"md5_digest": "19384a47918d30f56d8ceacf0b39504d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0.0,>=3.8.1",
"size": 19513,
"upload_time": "2025-07-30T10:34:19",
"upload_time_iso_8601": "2025-07-30T10:34:19.300108Z",
"url": "https://files.pythonhosted.org/packages/21/13/5de596a71246ada3ed0df2b003e544fc5a5b97ba372fe1deea21163ba5eb/django_sti_models-0.1.14-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "53fcaec0d148c0b824652584ca71f9568ebb69cf083065ea9843f45f109074e2",
"md5": "9ff7d7310c0785d5394214e80174a700",
"sha256": "2b57d19d34814cf0d883c17ad4a080d9640491800d71b5c8920e3ad9bfd0fe79"
},
"downloads": -1,
"filename": "django_sti_models-0.1.14.tar.gz",
"has_sig": false,
"md5_digest": "9ff7d7310c0785d5394214e80174a700",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0.0,>=3.8.1",
"size": 17095,
"upload_time": "2025-07-30T10:34:20",
"upload_time_iso_8601": "2025-07-30T10:34:20.723641Z",
"url": "https://files.pythonhosted.org/packages/53/fc/aec0d148c0b824652584ca71f9568ebb69cf083065ea9843f45f109074e2/django_sti_models-0.1.14.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-30 10:34:20",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "django-sti-models"
}