Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
103 lines (53 sloc) 3.53 KB

Custom Admin Actions For Querysets & Individual Objects

Allow editing in list view

When a model is heavily used to update the content, it makes to sense to allow bulk edits on the models.

class BookAdmin(admin.ModelAdmin):
    list_editable = ('author',)

Custom Actions On Querysets

Django provides admin actions which work on a queryset level. By default, django provides delete action in the admin.

In our books admin, we can select a bunch of books and delete them.

images/admin-custom-actions1.png

Django provides an option to hook user defined actions to run additional actions on selected items. Let us write write a custom admin action to mark selected books as available.

class BookAdmin(admin.ModelAdmin):
    actions = ('make_books_available',)
    list_display = ('id', 'name', 'author')

    def make_books_available(self, modeladmin, request, queryset):
        queryset.update(is_available=True)
    make_books_available.short_description = "Mark selected books as available"

images/admin-custom-actions2.png

Custom Actions On Individual Objects

Custom admin actions are inefficient when taking action on an individual object. For example, to delete a single user, we need to follow these steps.

  1. Select the checkbox of the object.
  2. Click on the action dropdown.
  3. Select "Delete selected" action.
  4. Click on Go button.
  5. Confirm that the objects needs to be deleted.

Just to delete a single record, we have to perform 5 clicks. That's too many clicks for a single action.

To simplify the process, we can have delete button at row level. This can be achieved by writing a function which will insert delete button for every record.

ModelAdmin instance provides a set of named URLs for CRUD operations. To get object url for a page, URL name will be {{ app_label }}_{{ model_name }}_{{ page }}.

For example, to get delete URL of a book object, we can call reverse("admin:book_book_delete", args=[book_id]). We can add a delete button with this link and add it to list_display so that delete button is available for individual objects.

from django.contrib import admin
from django.utils.html import format_html

from book.models import Book


class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'author', 'is_available', 'delete')

    def delete(self, obj):
        view_name = "admin:{}_{}_delete".format(obj._meta.app_label, obj._meta.model_name)
        link = reverse(view_name, args=[book.pk])
        html = '<input type="button" onclick="location.href=\'{}\'" value="Delete" />'.format(link)
        return format_html(html)

Now in the admin interface, we have delete button for individual objects.

images/admin-custom-actions3.png

To delete an object, just click on delete button and then confirm to delete it. Now, we are deleting objects with just 2 clicks.

In the above example, we have used an inbuilt model admin delete view. We can also write custom view and link those views for custom actions on individual objects. For example, we can add a button which will mark the book status to available.

In this chapter, we have seen how to write custom admin actions which work on single item as well as bulk items.

You can’t perform that action at this time.