Nested inlines in the Django admin?

27,421

Solution 1

As of now there is no "built-in" way to have nested inlines (inline inside inline) in django.contrib.admin. Pulling something like this off is possible by having your own ModelAdmin and InlineModelAdmin subclasses that would enable this kind of functionality. See the patches on this ticket http://code.djangoproject.com/ticket/9025 for ideas on how to implement this. You'd also need to provide your own templates that would have nested iteration over both the top level inline and it's child inline.

Solution 2

There is now this egg available, which is a collation of the relevant patches mentioned in the other answer:

https://github.com/theatlantic/django-nested-admin

Solution 3

I have done this using https://github.com/theatlantic/django-nested-admin, for the following Data structure:

  • Contest
    • Judges
    • Contestants
      • Singers
      • Songs

My admin.pyfile:

from django.contrib import admin
import nested_admin

from .models import Contest, Contestant, Judge, Song, Singer    

class SongInline(nested_admin.NestedTabularInline):
    model = Song
    extra = 0

class SingerInline(nested_admin.NestedTabularInline):
    model = Singer
    extra = 0

class ContestantInline(nested_admin.NestedTabularInline):
    model = Contestant
    inlines = [SongInline, SingerInline]
    extra = 0

class JudgeInline(nested_admin.NestedTabularInline):
    model = Judge
    extra = 0

class ContestAdmin(nested_admin.NestedModelAdmin):
    model = Contest
    inlines = [ContestantInline, JudgeInline]
    extra = 0

admin.site.register(Contest, ContestAdmin)

https://github.com/theatlantic/django-nested-admin appears to be much more actively maintained than the other apps already mentioned (https://github.com/BertrandBordage/django-super-inlines and https://github.com/Soaa-/django-nested-inlines)

Solution 4

I have just ran into this issue as well... Seems this thread which contains the request for the nested inlines feature (https://code.djangoproject.com/ticket/9025#no2) has been updated with further information.

A custom made app called "django-super-inline" has been released. More details here: https://github.com/BertrandBordage/django-super-inlines

Installation and usage instructions below.

Hope this is useful for whomever comes across this.

enter image description here

Solution 5

I ran into a similar issue to this. My approach was to make an UpdateAdmin that held inlines for both Media and Post... it basically just makes it so you have a list of all of the media entries followed by all of the posts in an update.

class MediaInline(admin.StackedInline):
        model = Media

class PostInline(admin.StackedInline):
        model = Post

class PostAdmin(admin.ModelAdmin):
        inlines = [MediaInline,]

class UpdateAdmin(admin.ModelAdmin):
        inlines = [MediaInline,PostInline]

It isn't an ideal solution but it works for a quick and dirty work around.

Share:
27,421
user1708601
Author by

user1708601

I'm the technical director for an animation and general CGI studio - Thaumaturgy Studios. We specialize in character-driven corporate media solutions. Our offerings include 3D visualisation, instructional media, medical imaging, music videos, mascot design, multimedia websites, accident/crime reconstruction, game design, television commercials, animated shorts, and a range of services to assist anyone undertaking any aspect of a project involving computer-generated imagery. It's a fun job - lots of variety, and some interesting challenges. I'm always happy to chat with other people in the industry about pipelines or possible collaboration.

Updated on December 13, 2020

Comments

  • user1708601
    user1708601 over 3 years

    Alright, I have a fairly simple design.

    class Update(models.Model):
        pub_date = models.DateField()
        title = models.CharField(max_length=512)
    
    class Post(models.Model):
        update = models.ForeignKey(Update)
        body = models.TextField()
        order = models.PositiveIntegerField(blank=True)
    
    class Media(models.Model):
        post = models.ForeignKey(Post)
        thumb = models.ImageField(upload_to='frontpage')
        fullImagePath = models.ImageField(upload_to='frontpage')
    

    Is there an easy-ish way to allow a user to create an update all on one page?

    What I want is for a user to be able to go to the admin interface, add a new Update, and then while editing an Update add one or more Posts, with each Post having one or more Media items. In addition, I want the user to be able to reorder Posts within an update.

    My current attempt has the following in admin.py:

    class MediaInline(admin.StackedInline):
        model = Media
    
    class PostAdmin(admin.ModelAdmin):
        inlines = [MediaInline,]
    

    This let's the user add a new Post item, select the relevant Update, add the Media items to it, and hit save - which is fine. But there's no way to see all the Posts that belong to a given Update in a single place, which in turn means you can't roderder Posts within an update. It's really quite confusing for the end user.

    Help?

  • andilabs
    andilabs about 10 years
    is it still up-to-date state of django?
  • whale_steward
    whale_steward over 8 years
    is it working for django 1.8 ? the last commit is in 2013
  • Bryce Guinta
    Bryce Guinta about 8 years
    @andi The ticket has been assigned For now pypi.python.org/pypi/django-nested-admin
  • Sashko Lykhenko
    Sashko Lykhenko over 7 years
    as of now, it does not support python 3
  • undefined
    undefined over 2 years
    What does extra = 0 mean?
  • undefined
    undefined over 2 years
    Ok this is a setting to show n empty rows so that new items can be added. With 0 empty rows you have to click on the 'Add another ... Relationship' button. Sorry for the email SPAM.