django-admin-extra-buttons
This is a full rewriting of the original django-admin-extra-url
. It
provides decorators to easily add custom buttons to Django Admin pages and/or add views to any ModelAdmin
It allows easy creation of wizards, actions and/or links to external resources as well as api only views.
Four decorators are available:
- @button() to mark a method as extra view and show related button
- @link() This is used for "external" link, where you don't need to invoke local views.
- @view() View only decorator, this adds a new url but do not render any button.
- @choice() Menu like button, can be used to group multiple @views().
How to use it
class Admin1(ExtraButtonsMixin, admin.ModelAdmin):
list_filter = [TestFilter]
@button(permission="demo.add_demomodel1", change_form=True, change_list=False, html_attrs={"class": "aeb-green"})
def refresh(self, request):
self.message_user(request, "refresh called")
@button(label="Refresh", permission=lambda request, object, **kw: False)
def refresh_callable(self, request):
opts = self.model._meta
self.message_user(request, "refresh called")
return HttpResponseRedirect(reverse(admin_urlname(opts, "changelist")))
@button(pattern="a/b/")
def custom_path(self, request):
opts = self.model._meta
self.message_user(request, "You invoked `custom_path` linked to 'a/b/' url ")
return HttpResponseRedirect(reverse(admin_urlname(opts, "changelist")))
@button(html_attrs={"style": "background-color:#EDD372;color:black"})
def no_response(self, request):
self.message_user(request, "No Response provided.")
@button(html_attrs={"style": "background-color:#DC6C6C;color:black"})
def confirm(self, request):
def _action(request: HttpRequest) -> None:
pass
return confirm_action(
self,
request,
_action,
message="Confirm action",
success_message="Successfully executed",
)
@button(permission="demo.delete_demomodel1")
def update(self, request, pk):
opts = self.model._meta
self.message_user(request, "action called")
return HttpResponseRedirect(reverse(admin_urlname(opts, "changelist")))
@button()
def no_response_single(self, request, object_id):
self.message_user(request, "No_response_obj.")
@button(permission=lambda request, obj, **kw: False)
def update_callable_permission(self, request, object_id):
opts = self.model._meta
self.message_user(request, "action called")
return HttpResponseRedirect(reverse(admin_urlname(opts, "changelist")))
@button(pattern="a/b/<path:object_id>")
def custom_update(self, request, object_id):
opts = self.model._meta
self.message_user(request, "action called")
return HttpResponseRedirect(reverse(admin_urlname(opts, "changelist")))
@button(visible=lambda btn: "BTN_SHOW" in os.environ)
def custom_visibile(self, request):
pass
@button(enabled=False)
def disabled(self, request):
pass
@button(enabled=lambda btn: "BTN_ENABLED" in os.environ)
def enabled(self, request):
pass
@link(href="https://www.google.com/", visible=lambda btn: True)
def invisible(self, button):
button.visible = False
@button()
def error_message(self, request):
try:
1 / 0
except Exception as e: # noqa: BLE001
self.message_error_to_user(request, e)