Search code examples
pythondjangohyperlinkdjango-adminnonetype

How to avoid admin.E111 error in Django 1.9.2?


Up until Django 1.8.x I had this code in my admin.py file:

class MyClassAdmin(admin.ModelAdmin):
    # ...
    list_display = ('field1', 'field2', 'field3')

    def __init__(self, *args, **kwargs):
        super(MyClassAdmin, self).__init__(*args, **kwargs)
        self.list_display_links = (None, )

This was meant to disable the link on the rows of the Model when the users opened it. I need this because this refers to a read-only table and I don't want users to be able to even edit entries.

Recently, I upgraded to Django 1.9.2, and this code is currently returning an error:

django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:

ERRORS: <class 'myapp.admin.MyClassAdmin'>: (admin.E111) The value of 'list_display_links[0]' refers to 'None', which is not defined in 'list_display'.

As per the Django docs, this is:

admin.E111: The value of list_display_links[n] refers to , which is not defined in list_display.

This is quite vague and doesn't explain how to handle non-string values such as None.

How can I modify this piece of code so I can overwrite the list_display_links attribute in the __init__ function?


Solution

  • The docs for list_display_links say that you should use None if you do not want to display any links. You are returning a tuple, which means that Django expects each item in the tuple to be a field in list_display. Since None is not a field, you get the error from the checks framework.

    As an aside, it's not recommended to set self.list_display_links in the model admin's __init__ method. It would be better to set list_display_links on the class.

    class MyClassAdmin(admin.ModelAdmin):
        ...
        list_display = ('field1', 'field2', 'field3')
        list_display_links = None
    

    Or, if you need to change it dynamically, then override get_list_display_links.

    class MyClassAdmin(admin.ModelAdmin):
        ...
        list_display = ('field1', 'field2', 'field3')
    
        def get_list_display_links(request, list_display):
            if condition():
                return None
            else:
                return list_display