Opened 4 weeks ago

Last modified 4 weeks ago

#35464 new Cleanup/optimization

Fieldsets defined for TabularInlines are ignored

Reported by: Natalia Bidart Owned by: nobody
Component: contrib.admin Version: dev
Severity: Normal Keywords:
Cc: Marijke Luttekes, Thibaud Colas, Tom Carrick, Sarah Abderemane Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description

Following the review of the PR solving #35189 and the analysis done in #35456, I found out that when defining an admin model with a TabularInline instance which defines fieldsets, those fieldsets are "ignored" in the UI (in terms of actually using a fieldset element, the content is shown).
Furthermore, if the fieldsets include the collapse CSS class, nothing changes in the UI and there is not way of having collapsible fieldsets inside TabularInlines. See attached screenshots and some example models down below.

Regarding how to fix this, I see two options:

  1. Discuss with the accessibility plan whether there is a way to structure HTML to have "collapsible fieldsets" inside a tabular context, or
  2. Explicitly document that fieldsets make no sense for TabularInline. The current docs imply this setup is valid:

InlineModelAdmin.classes
A list or tuple containing extra CSS classes to apply to the fieldset that is rendered for the inlines. Defaults to None. As with classes configured in fieldsets, inlines with a collapse class will be initially collapsed and their header will have a small “show” link.

Example modes and admin models:

  • models.py
    from django.db import models
    from django.utils.timezone import now
    
    
    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=100)
        publisher = models.CharField(max_length=100)
        creation_date = models.DateField(default=now)
        update_date = models.DateField(default=now)
        publication_date = models.DateField(default=now)
    
        def __str__(self):
            return self.title
    
    
    class Cover(models.Model):
        book = models.ForeignKey(Book, on_delete=models.CASCADE)
        image = models.CharField(max_length=100)
        title = models.CharField(max_length=100)
        description = models.TextField()
        creation_date = models.DateField(default=now)
        update_date = models.DateField(default=now)
        updated_by = models.CharField(max_length=100)
    
  • admin.py
    from django.db import models
    from django.contrib import admin
    
    from .models import Book, Cover
    
    
    class CoverInlineMixin:
        model = Cover
        extra = 2
        fieldsets = (
            (None, {"fields": ("image", "title")}),
            ("Details", {
                "fields": ("description", "creation_date"),
                "classes": ("collapse",),
            }),
            ("Details", {
                "fields": ("update_date", "updated_by"),
                "classes": ("collapse",),
            }),
        )
    
    
    class CoverTabularInline(CoverInlineMixin, admin.TabularInline):
        pass
    
    
    class CoverStackedInline(CoverInlineMixin, admin.StackedInline):
        pass
    
    
    class BookAdmin(admin.ModelAdmin):
        list_display = ("title", "author", "publisher","publication_date")
        search_fields = ("title", "author")
        list_filter = ("author", "publication_date")
        fieldsets = (
            (None, {
                "fields": ("title", "author")
            }),
            ("Advanced options", {
                "classes": ("collapse",),
                "fields": ("publisher", "publication_date",)
            }),
            ("Advanced options", {
                "classes": ("collapse",),
                "fields": ("creation_date", "update_date",)
            }),
        )
        inlines = [
            CoverTabularInline,
            CoverStackedInline,
        ]
    
    
    admin.site.register(Book, BookAdmin)
    

Attachments (1)

image-20240517-114532.png (114.5 KB ) - added by Natalia Bidart 4 weeks ago.

Download all attachments as: .zip

Change History (4)

by Natalia Bidart, 4 weeks ago

Attachment: image-20240517-114532.png added

comment:1 by Natalia Bidart, 4 weeks ago

Cc: Marijke Luttekes Thibaud Colas Tom Carrick Sarah Abderemane added
UI/UX: set

comment:2 by Sarah Boyce, 4 weeks ago

Triage Stage: UnreviewedAccepted

I think this is a little similar to #21353 where a note was added to "description" but I think this note should be pulled out and generally be stated for TabularInlines
I would vote option 2 and have a note 👍

comment:3 by Marijke Luttekes, 4 weeks ago

I am still unsure of what the UI would be for fieldsets (collapsible or otherwise) in TabularInlines.

A tabular inline is a table; tables are naturally single-use elements: a table contains cells, an optional caption, and nothing more fancy.
They are also very consistent in that they are just as annoying to customize, style, and make responsive as they were many years ago.

There was a suggestion to make the columns collapsible instead. This is not something that can be achieved without using custom JavaScript.
Per the specs, the HTML collapsible details element is not allowed within a table, nor did it work when one of our Discord members tried it in a proof of concept.

Per the above, I am also in favor of option 2.

Note: See TracTickets for help on using tickets.
Back to Top