Reputation: 6345
Is there a way to define short_description for a field in ModelAdmin as callable - sometimes one wants to provide extra dynamic information inside column names.
Or are there any ugly hacks that accomplish the same goals?
Upvotes: 5
Views: 1440
Reputation: 2935
The only thing that worked for me was to override get_readonly_fields/get_list_display
as described in this answer: https://stackoverflow.com/a/66028062
@admin.register(models.EmployeeTrainingRecord)
class EmployeeTrainingRecordAdmin(admin.ModelAdmin):
ordering = ('email',)
list_display = [
'id',
'first_name',
'last_name',
]
def get_queryset(self, request):
return (
super().get_queryset(request)
.annotate_training_dates()
)
def get_list_display(self, request):
list_display = super().get_list_display(request)
training_modules = models.Training.objects.all()
for training in training_modules:
attr_name = 'training_%s' % training.id
if not hasattr(self, attr_name):
list_display.append(attr_name)
func = partial(self._get_training_id, field=attr_name)
func.short_description = training.name
setattr(self, attr_name, func)
return list_display
@staticmethod
def _get_training_id(obj, field=''):
return getattr(obj, field, '')
Upvotes: 0
Reputation: 6345
Peter DeGlopper's answer provided the needed direction - despite the fact that since the djangosnippet's posting a lot of things have changed.
This is indeed working:
class MyAdmin(admin.ModelAdmin):
list_display = ('my_callable')
class MyCallable:
def __call__(self, obj):
return 42
@property
def __name__(self):
return 'Galaxy'
@property
def my_callable(self):
if not hasattr(self, __my_callable):
self.__my_callable = self.MyCallable()
return self__my_callable
Importantly enough, the MyAdmin
object is not passed to the MyCallable.__call__()
call - if you need access to it, pass it in the __init__
initializer yourself.
Upvotes: 1
Reputation: 37364
As far as I know/remember properties can only be defined on new-style classes, in the class definition. So your ModelAdmin
field would have to resolve to a callable object with the desired property. This snippet looks to me like it should allow that:
https://djangosnippets.org/snippets/2447/
The field itself becomes a property that resolves to an instance of the VotesToday
class, on which short_description
is also a property.
Upvotes: 2