Skip to content

Commit

Permalink
add custom object-tools
Browse files Browse the repository at this point in the history
  • Loading branch information
cuongnb14 committed Feb 24, 2023
1 parent ddf485d commit 0c005a2
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 5 deletions.
4 changes: 2 additions & 2 deletions admin_extended/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.contrib import admin
from django.shortcuts import render
from django.urls import path
from .mixins import UIUtilsMixin, ChangeFormActionAdminModelMixin
from .mixins import UIUtilsMixin, ChangeFormActionAdminModelMixin, ObjectToolModelAdminMixin
from .settings import ADMIN_EXTENDED_SETTINGS


Expand All @@ -13,7 +13,7 @@ def has_search_fields(field):
return model_admin and model_admin.search_fields


class ExtendedAdminModel(ChangeFormActionAdminModelMixin, UIUtilsMixin, admin.ModelAdmin):
class ExtendedAdminModel(ObjectToolModelAdminMixin, UIUtilsMixin, admin.ModelAdmin):
"""
Extend base model admin: tabbable inline model, separate view, edit model,...
Expand Down
11 changes: 11 additions & 0 deletions admin_extended/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def object_tool(function=None, *, icon=None, name=None, description=None):
def decorator(func):
func.icon = icon
func.name = name
func.description = description

return func

if function is None:
return decorator
return decorator(function)
90 changes: 88 additions & 2 deletions admin_extended/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def get_urls(self):
def get_change_form_actions(self, request, object_id):
return [x() for x in self.change_form_action_classes]

def get_change_form_object_tools(self, request, object_id):
def get_change_form_object_tools1(self, request, object_id):
return self.change_form_object_tools

def change_from_action_view(self, request):
Expand All @@ -74,7 +74,93 @@ def _changeform_view(self, request, object_id, form_url, extra_context):
extra_context['change_form_actions'] = change_form_actions
extra_context['change_form_action_url'] = reverse(action_url_name)

change_form_object_tools = self.get_change_form_object_tools(request, object_id)
change_form_object_tools = self.get_change_form_object_tools1(request, object_id)
extra_context['change_form_object_tools'] = change_form_object_tools

return super()._changeform_view(request, object_id, form_url, extra_context)

class ObjectToolModelAdminMixin:
change_form_object_tools = []
change_list_object_tools = []

def get_urls(self):
urls = super().get_urls()

base_url_name = "%s_%s" % (self.model._meta.app_label, self.model._meta.model_name)
custom_urls = [
path(
'<int:object_id>/object-tools/<str:name>',
self.admin_site.admin_view(self.change_form_object_tool_view),
name=f'{base_url_name}_change_form_object_tool'
),
path(
'object-tools/<str:name>',
self.admin_site.admin_view(self.change_list_object_tool_view),
name=f'{base_url_name}_change_list_object_tool'
),
]
return custom_urls + urls

def get_change_form_object_tools(self, request):
object_tools = []
for change_form_object_tool in self.change_form_object_tools:
object_tool = getattr(self, change_form_object_tool)
object_tools.append(object_tool)
return {object_tool.name: object_tool for object_tool in object_tools}


def change_form_object_tool_view(self, request, object_id, name):
change_form_object_tools = self.get_change_form_object_tools(request)
return change_form_object_tools[name](request, object_id)


def _get_render_change_form_object_tools(self, request, object_id):
base_url_name = "%s_%s" % (self.model._meta.app_label, self.model._meta.model_name)
change_form_object_tools = self.get_change_form_object_tools(request)
result = []
for name, object_tool in change_form_object_tools.items():
result.append({
'icon': object_tool.icon,
'url': reverse(f'admin:{base_url_name}_change_form_object_tool', args=[object_id, name]),
'description': object_tool.description,
})
return result


def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
if object_id:
extra_context = extra_context if extra_context else {}
extra_context['change_form_object_tools'] = self._get_render_change_form_object_tools(request, object_id)

return super().changeform_view(request, object_id, form_url, extra_context)


def get_change_list_object_tools(self, request):
object_tools = []
for change_list_object_tool in self.change_list_object_tools:
object_tool = getattr(self, change_list_object_tool)
object_tools.append(object_tool)
return {object_tool.name: object_tool for object_tool in object_tools}


def change_list_object_tool_view(self, request, name):
change_list_object_tools = self.get_change_list_object_tools(request)
return change_list_object_tools[name](request)

def _get_render_change_list_object_tools(self, request):
base_url_name = "%s_%s" % (self.model._meta.app_label, self.model._meta.model_name)
change_list_object_tools = self.get_change_list_object_tools(request)
result = []
for name, object_tool in change_list_object_tools.items():
result.append({
'icon': object_tool.icon,
'url': reverse(f'admin:{base_url_name}_change_list_object_tool', args=[name]),
'description': object_tool.description,
})
return result

def changelist_view(self, request, extra_context=None):
extra_context = extra_context if extra_context else {}
extra_context['change_list_object_tools'] = self._get_render_change_list_object_tools(request)

return super().changelist_view(request, extra_context)
8 changes: 8 additions & 0 deletions admin_extended/templates/admin/change_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends "admin/change_list.html" %}

{% block object-tools-items %}
{% for item in change_list_object_tools %}
<li><a href="{{ item.url }}"><i class="{{ item.icon }}"></i> {{ item.description }}</a></li>
{% endfor %}
{{ block.super }}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{% for item in change_form_object_tools %}
<li><a href="{{ item.url }}"><i class="{{ item.icon }}"></i> {{ item.title }}</a></li>
<li><a href="{{ item.url }}"><i class="{{ item.icon }}"></i> {{ item.description }}</a></li>
{% endfor %}

0 comments on commit 0c005a2

Please sign in to comment.