Skip to content

Instantly share code, notes, and snippets.

@code-shoily
Last active June 9, 2018 02:36
Show Gist options
  • Save code-shoily/5ae86df0f60e7667661a28776318e7a4 to your computer and use it in GitHub Desktop.
Save code-shoily/5ae86df0f60e7667661a28776318e7a4 to your computer and use it in GitHub Desktop.
Answer to Python Bangladesh question regarding adding button in admin.
"""
This is from an actual snippet of mine, trimmed down, in order to answer a question asked in Python Bangladesh Group on
adding extra buttons in Admin list.
"""
from django.contrib import admin
from django.urls import reverse
from django.utils.html import mark_safe
from .models import *
@admin.register(Task)
class TaskAdmin(admin.ModelAdmin):
list_display = ["title", "deadline", "actions"] # <----- Be sure to add actions in list_display
def actions(self, instance):
"""
This is method adds the button, you can put any HTML you like in here, just remember to wrap the
returning string with mark_safe (Django 2.0+). In older versions, you could get away with a
method_name.allow_tags = True, but don't do it, mark_safe is the de facto way.
This method could also have been in the Task method as a property/method, but I suggest it is better
to put as an admin member because this has only usage in admin, domain-wise, it belongs to the admin.
See how I used reverse to get the URL out of a view_name (given the ID) and plug it on the HTML
snippet, you can use <button> too if you want, (but better use link styled as button I'd say).
With adding mark_save and adding the method name (be sure to put, self, instance as parameters where
instance is the model instance this admin is registered for) in list_display, you can put any HTML
you want, be it tiny barcodes, image thumbnails or buttons. Just in case of extra URLs, you need to
also define the methods below.
"""
url_name = reverse("admin:task_task_detail", kwargs={"id": str(instance.id)})
return mark_safe('<a class="btn" href={}>View</a>'.format(url_name))
def detail_view(self, request, id):
"""
This is the view, you can have as many views as you want and treat them like Django views.
They can be outside in the views.py or admin_views.py files too if you wish.
"""
task = Task.objects.get(id=id)
return HttpResponse("Task INFO: {}".format(task.desribe()))
def get_urls(self):
"""
This method gives this admin some extra urls, you add the urls and point them to legit views.
The view names are namespaced with admin and are named like admin:view_name.
"""
urls = super().get_urls()
extra_urls = [
url(r'^detail/(?P<id>.+)/$',
self.admin_site.admin_view(self.detail_view),
name="task_task_detail"),
]
return extra_urls + urls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment