Django Nested Admin
django-nested-admin provides Django admin classes that allow for deeply nested inlines within the Django administration interface. It extends Django's native `InlineModelAdmin` functionality to support multiple levels of related objects. The current version is 4.1.6, and it typically releases new versions to maintain compatibility with new Django releases.
Warnings
- breaking Version 4.0.0 removed Python 2.x compatibility and dropped support for all Django versions prior to 3.2. Projects on older Django or Python versions must upgrade or use an older `django-nested-admin` release.
- breaking Version 4.1.0 updated the signature for `formfield_for_dbfield` and removed usage of deprecated `filter` methods within the codebase. Custom admin classes overriding `formfield_for_dbfield` might need signature adjustments.
- gotcha `django-nested-admin` often requires strict alignment with Django's major version. Upgrading Django may necessitate a corresponding upgrade of `django-nested-admin` to ensure compatibility and prevent unexpected behavior or errors.
- gotcha Integration with `django-grappelli` can sometimes be tricky due to differences in frontend assets and JavaScript event handling. While `django-nested-admin` includes specific fixes for Grappelli, incompatibilities can still arise with certain versions.
- gotcha If you are using Django's autocomplete fields or other custom JavaScript in your admin, be aware that `django-nested-admin` (especially v4.0.0+) dispatches native JavaScript CustomEvent events like `formset:added` and `formset:removed`. Your custom JS might need to listen for these.
Install
-
pip install django-nested-admin
Imports
- NestedModelAdmin
from nested_admin import NestedModelAdmin
- NestedStackedInline
from nested_admin import NestedStackedInline
- NestedTabularInline
from nested_admin import NestedTabularInline
Quickstart
from django.contrib import admin
from django.db import models
from nested_admin import NestedModelAdmin, NestedStackedInline, NestedTabularInline
# Example Models
class Grandparent(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Parent(models.Model):
grandparent = models.ForeignKey(Grandparent, on_delete=models.CASCADE, related_name='parents')
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Child(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')
name = models.CharField(max_length=100)
def __str__(self):
return self.name
# Admin Inlines
class ChildInline(NestedTabularInline):
model = Child
extra = 1
class ParentInline(NestedStackedInline):
model = Parent
inlines = [ChildInline]
extra = 1
@admin.register(Grandparent)
class GrandparentAdmin(NestedModelAdmin):
inlines = [ParentInline]
list_display = ('name',)
# Register Parent and Child models to ensure they appear in admin if not directly inline
# admin.site.register(Parent)
# admin.site.register(Child)