From 03ae00ae34ebde88fc3da7c7c3d3c7c5826ec615 Mon Sep 17 00:00:00 2001 From: henribru <6639509+henribru@users.noreply.github.com> Date: Fri, 15 May 2020 16:08:22 +0200 Subject: [PATCH] Increase admin list panel performance by selecting related (#134) * Increase admin panel performance by selecting related * Use `get_changelist_instance` override --- easyaudit/admin.py | 21 ++++++++++++++------- easyaudit/admin_helpers.py | 7 ++++++- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/easyaudit/admin.py b/easyaudit/admin.py index 1e582a4a..b4de9661 100644 --- a/easyaudit/admin.py +++ b/easyaudit/admin.py @@ -26,13 +26,19 @@ class CRUDEventAdmin(EasyAuditModelAdmin): 'user_pk_as_string', 'datetime', 'changed_fields_prettified'] exclude = ['object_json_repr', 'changed_fields'] + def get_changelist_instance(self, *args, **kwargs): + changelist_instance = super().get_changelist_instance(*args, **kwargs) + content_type_ids = [obj.content_type_id for obj in changelist_instance.result_list] + self.content_types_by_id = {content_type.id: content_type for content_type in ContentType.objects.filter(id__in=content_type_ids)} + return changelist_instance + def get_content_type(self, obj): - return ContentType.objects.get(id=obj.content_type_id) + return self.content_types_by_id[obj.content_type_id] get_content_type.short_description = "Content Type" def get_user(self, obj): - return get_user_model().objects.filter(id=obj.user_id).first() + return self.users_by_id.get(obj.user_id) get_user.short_description = "User" @@ -41,9 +47,10 @@ def object_repr_link(self, obj): html = obj.object_repr else: try: + content_type = self.get_content_type(obj) url = reverse("admin:%s_%s_change" % ( - obj.content_type.app_label, - obj.content_type.model, + content_type.app_label, + content_type.model, ), args=(obj.object_id,)) html = '%s' % (url, obj.object_repr) except: @@ -76,12 +83,12 @@ class LoginEventAdmin(EasyAuditModelAdmin): readonly_fields = ['login_type', 'get_username', 'get_user', 'remote_ip', 'datetime', ] def get_user(self, obj): - return get_user_model().objects.filter(id=obj.user_id).first() + return self.users_by_id.get(obj.user_id) get_user.short_description = "User" def get_username(self, obj): - user = get_user_model().objects.filter(id=obj.user_id).first() + user = self.get_user(obj) username = user.get_username() if user else None return username @@ -101,7 +108,7 @@ class RequestEventAdmin(EasyAuditModelAdmin): readonly_fields = ['url', 'method', 'query_string', 'get_user', 'remote_ip', 'datetime', ] def get_user(self, obj): - return get_user_model().objects.filter(id=obj.user_id).first() + return self.users_by_id.get(obj.user_id) get_user.short_description = "User" diff --git a/easyaudit/admin_helpers.py b/easyaudit/admin_helpers.py index 52a50c6e..11ae9b82 100644 --- a/easyaudit/admin_helpers.py +++ b/easyaudit/admin_helpers.py @@ -30,9 +30,14 @@ def prettify_json(json_string): class EasyAuditModelAdmin(admin.ModelAdmin): + def get_changelist_instance(self, *args, **kwargs): + changelist_instance = super().get_changelist_instance(*args, **kwargs) + user_ids = [obj.user_id for obj in changelist_instance.result_list] + self.users_by_id = {user.id: user for user in get_user_model().objects.filter(id__in=user_ids)} + return changelist_instance def user_link(self, obj): - user = get_user_model().objects.filter(id=obj.user_id).first() + user = self.users_by_id.get(obj.user_id) #return mark_safe(get_user_link(user)) if user is None: return '-'