Django Admin: Setting list_display conditionally
Is there any admin model method like get_list_display() or some way that I can have some conditions to set different list_display values?
class FooAdmin (model.Mod开发者_Go百科elAdmin):
# ...
def get_list_display ():
if some_cond:
return ('field', 'tuple',)
return ('other', 'field', 'tuple',)
The ModelAdmin
class has a method called get_list_display
which takes request as a parameter, by default returning the list_display
property of the class.
So you can do for example:
class ShowEFilter(SimpleListFilter):
""" A dummy filter which just adds a filter option to show the E column,
but doesn't modify the queryset.
"""
title = _("Show E column")
parameter_name = "show_e"
def lookups(self, request, model_admin):
return [
("yes", "Yes"),
]
def queryset(self, request, queryset):
return queryset
class SomeModelAdmin(admin.ModelAdmin):
list_display = (
"a",
"b",
"c",
"d",
"e"
)
list_filter = (
ShowEFilter,
)
def get_list_display(self, request):
""" Removes the E column unless "Yes" has been selected in the
dummy filter.
"""
list_display = list(self.list_display)
if request.GET.get("show_e", "no") != "yes":
list_display.remove("e")
return list_display
Have you tried making that a property?
class FooAdmin(admin.ModelAdmin):
@property
def list_display(self):
if some_cond:
return ('field','tuple')
return ('other','field','tuple')
I haven't but it may work.
I'm also fairly certain you could spell it:
class FooAdmin(admin.ModelAdmin):
if CONDITION:
list_display = ('field','tuple')
else:
list_display = ('other','field','tuple')
But this one would only run the check at the time the FooAdmin class is interpreted: but if you were basing the test on settings.SOME_VALUE, for instance, then it may work.
Note also that the self
in the first example is the instance of the FooAdmin class, not Foo itself.
You want to override the changelist_view method of the admin.ModelAdmin class:
def changelist_view(self, request, extra_context=None):
# just in case you are having problems with carry over from previous
# iterations of the view, always SET the self.list_display instead of adding
# to it
if something:
self.list_display = ['action_checkbox'] + ['dynamic_field_1']
else:
self.list_display = ['action_checkbox'] + ['dynamic_field_2']
return super(MyModelAdminClass, self).changelist_view(request, extra_context)
The 'action_checkbox' is what django uses to know to display the checkbox on the left hand side for the action drop down, so make sure you include it in setting the self.list_display. As usual if you simply set list_display for the ModelAdmin class normally you don't need to include it.
精彩评论