My goal is to make some fields editable in the list view. But the problem is that the fields are determined dynamically using get_list_display. Moveover, I would like to define the elements of the list_editable to be dynamic as well. However, Django does not seem to provide any method like get_editable_list. Is it made deliberately ? How can this be achieved ?
Now my code looks like this:
class MyModelAmdin(admin.ModelAdmin):
list_editable = ('field1')
# change_list_template = "files_changelist.html"
def get_list_display(self, request):
if request.user.is_superuser:
list_display = ('field1', 'field2',)
else:
list_display = ('field1',)
return list_display
Django (justfully) complains that some of the fields which are not included in the list_display are included in the list_editable. Any way ouy?
Good question!! Required a bit of digging in the code, but...
Django does not seem to provide any method like get_editable_list
Yes, this is correct. Django doesn't provide any built in method to do this.
Is it made deliberately ?
I'm not sure, it could be an oversight, but I suspect not. The check that makes sure there is nothing in list_editable that isn't in list_display is run right at the beginning when django starts up, you can't even runserver with this condition. The fact that it is checked in this way, rather than just raising a normal error, makes me think there is good reason to make absolutely certain this condition is held. Adding a dynamic way to set list_editable would make such a check impossible.
How can this be achieved ?
There are a few methods inside ModelAdmin which use self.list_editable. You could reimplement them to use your own self.get_list_editable(request) method. I think the easiest way however would be to overwrite changelist_view and set list_editable before anything else, then all the other methods will be using the correct list_editable e.g:
class MyModelAdmin(admin.modelAdmin):
list_editable=() # so the check passes - or can just omit this line completely
def get_list_editable(self, request):
# whatever you want here
def changelist_view(self, request, extra_context=None):
self.list_editable = self.get_list_editable(request)
return super().changelist_view(request, extra_context)
Just test thoroughly and make 100% sure that your get_list_editable and get_list_display methods won't lead to a situation where you have something in list_editable that is not in list_display.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With