How to override a class in django.contrib.admin ?

Hello again,

How to override the ChangeList class in django.contrib.admin.views.main, and tell django to use it instead of the original one?

Hopefully this time I get some answers.

Thanks

The short, direct, and specific answer to your question is that you either go into the Django source code and modify that class, or you “monkey patch” it. Neither option is particularly recommended unless it’s absolutely necessary.

What specific behavior are you looking to alter in that class? It’s probably better to approach this from trying to understand what needs to be modified.

this patch: django_ordering.py.diff on Ticket #34646 – Attachment – Django

Because @Mariusz Felisiak thinks, and I quote:

it looks niche. We don’t want to add unnecessary complexity to the API.

Although, @Petr Dlouhý is 100% right when he said, and I quote:

On one hand it is small modification of Django code and small increase in API complexity (which is consistent with the logic of other order fields, BTW)

it’s inconsistent that one time the ordering accepts only one field, but in another time, it accepts multiple fields.

I do not see how this small modification will add “unnecessary complexity to the API” !!! really?

Ok, after lots of digging, I came up with this solution,

  1. Create a new file where it’s going to hold all the overrides:
touch project/core/overrides.py

Then edit it as follow:

# project/core/overrides.py 

from django.contrib.admin.views.main import ChangeList

# override: django.contrib.admin.views.main.ChangeList
class ChangeList(ChangeList):
   # your overridden code ...
  1. Create a custom ModelAdmin, then override the get_changelist() method:
touch project/core/admin.py

Then edit it as follow:

# project/core/admin.py

from django.contrib.admin import ModelAdmin

class CustomModelAdmin(ModelAdmin):
    def get_changelist(self, request, **kwargs):
        from .overrides import ChangeList
        return ChangeList
  1. Finally, in your app admin, instead of inheriting from admin.ModelAdmin, inherit from CustomModelAdmin:
# Project/app/admin.py

from django.contrib.admin import register
from core.admin import CustomModelAdmin
from .models import App

@register(App)
class AppAdmin(CustomModelAdmin):
    # your normal admin code ...

Hopefully someone, someday, somewhere, might find it helpful.