I'd like to dynamically include some extra fields in the list_display
of the admin for one of my models. I plan on overriding get_list_display
to append a string representing a ModelAdmin
method but how can I dynamically create the ModelAdmin
methods?
In the example below if get_list_display
returns [..., 'module_1', 'module_2']
that means I need methods for module_1
and module_2
as they're not model fields.
class Type(models.Model):
...
modules = models.ManyToManyField(Module)
class User(AbstractBaseUser):
...
type = models.ForeignKey(Type)
class UserModuleRecord(User):
class Meta:
proxy=True
@admin.register(UserModuleRecord)
class UserModuleRecordAdmin(admin.ModelAdmin):
list_display = ['id', 'first_name', 'last_name']
def get_queryset(self, request):
return (
super().get_queryset(request)
.annotate_the_additional_list_display_values()
)
def get_list_display(self, request):
list_display = super().get_list_display(request)
modules = Module.objects.all()
for module in modules:
list_display.append('module_%s' % module.id)
return list_display
Additionally is it possible to create something similar to how get_FOO_display
works so there's only one admin method required?
UPDATE
I think I'm close with the following but am getting an error TypeError: 'partialmethod' object is not callable
from functools import partialmethod
def get_list_display(self, request):
list_display = super().get_list_display(request)
modules = Module.objects.all()
for module in modules:
attr_name = 'module_%s' % module.id
list_display.append(attr_name)
if not hasattr(self, attr_name):
setattr(self, attr_name, partialmethod(
self._module_id, field=attr_name
))
return list_display
def _module_id(self, obj, field=''):
return getattr(obj, field, '')