Use same syntax for related objects in SnippetViewSet when overriding colums
Is your proposal related to a problem?
Sometimes we want to override the headings for fields in the list_display attribute and then we have to use the wagtail.admin.ui.tables.Column class. If the associated field is a related field, such as an author of a book, one would use the double underscore __ notation to navigate relations as is the standard in Django Querysets:
class BookAdmin(SnippetViewSet):
model = Book
list_display = ["title", "author__name"]
However, when using the Column class, we need to navigate relations using dot-notation:
class BookAdmin(SnippetViewSet):
model = Book
list_display = [Column("title", "Book title"), Column("author.name", "Book author")]
Describe the solution you'd like
I expected that when using Column I would have to use the same notation when referencing the related field, which is not the case. It would be best if Column and other related classes would accept the __ syntax for related models.
I think most users would expect the same syntax in both use cases.
Also, the documentation does not mention how to do related fields when using Column.
I can take this issue but need direction that should we only improve documentation by mentioning this notation or should we actually fix to uniform the notation
I'm not sure if this is something we want to do. On the surface it does make sense to make these uniform, but the reason why they differ is because of the implementation and the underlying principles.
- The tables framework, and thus the
Columnclass which is part of it, can work with any object list, not necessarily model instances. When this was implemented, we took themultigetattrfunction originally used forSpreadsheetExportMixin(list_export& co.). This function follows the same logic as Django templates' variable resolution logic: https://github.com/wagtail/wagtail/blob/b0b582ab5067e9c649ce0507ff00cb601f81f3ed/wagtail/coreutils.py#L347-L356 - This means the dot notation is more "powerful"/generic in the sense that it can traverse beyond model relations, e.g. it can be used to access properties of the related instance, or even nested dictionary keys.
- The
list_displayattribute is specific to the genericIndexViewthat works with Django models. We took the high-level API from wagtail-modeladmin (and in turn Django's ModelAdmin), and made it an abstraction forColumnthat automatically generates thelabel,sort_key, etc. from the model field. Support for related objects was added recently in #11588, using the double-underscore notation to follow the same feature also recently implemented by Django's ModelAdmin. (Somewhat related: this also ties nicely withlist_filterthat is passed along to django-filter, which supports the same double-underscore notation.)
My concern is that if we allow the double underscore notation for Column, would that also shift the expectation of behaviour, and whether we need to address it. Some design questions off the top of my head:
- Are we okay for the
Columnclass to handle the__syntax, which is typically used for working with Django models? - Do we simply convert
__into.and keep the rest of the logic, or do something more to ensure that we're traversing model relationships? If the former, then__now also works for accessing object properties, which isn't really applicable in other places. - Does this mean
.is interchangeable with__, i.e. can I use.to span relationships inlist_display?
Just to add to this. This does not only apply to situations where you override using Column. It is also a matter of inconsistency when using list_display and list_export. That is, it is not possible to traverse relationships in list_exports using the __ notation.
class MyAdmin(SnippetViewSet):
list_display = ('application__user',)
list_export = ('application.user',)