Django Admin list actions are meant to be used to perform operations in bulk. All Django Admin list views already come with a default action “Delete selected <ModelName>s”. In this short tutorial I will guide you through the steps to create your own list actions.
Creating the Action FunctionEach action in the list is a regular python function that takes three parameters: the current ModelAdmin , a HttpRequest object (just like a view function) and a QuerySet , which is the list of selected model instances.
Those Action Functions can live inside the admin.py module of your app. But if they start to get really big, you can define them outside the admin.py .
Following is the skeleton for a Action Function :
def my_admin_action(modeladmin, request, queryset): # do something with the queryset my_admin_action.short_description = 'My admin action'
Simple ExampleConsider the following model and model admin:
models.pyfrom django.db import models class Book(models.Model): HARDCOVER = 1 PAPERBACK = 2 EBOOK = 3 BOOK_TYPES = ( (HARDCOVER, 'Hardcover'), (PAPERBACK, 'Paperback'), (EBOOK, 'E-book'), ) title = models.CharField(max_length=50) publication_date = models.DateField(null=True) author = models.CharField(max_length=30, blank=True) price = models.DecimalField(max_digits=5, decimal_places=2) pages = models.IntegerField(blank=True, null=True) book_type = models.PositiveSmallIntegerField(choices=BOOK_TYPES) class Meta: verbose_name = 'book' verbose_name_plural = 'books'
admin.py from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] admin.site.register(Book, BookAdmin)Let’s say we want to create a list action to apply a 10% discount to the selected books. It would be as simple as:
admin.py import decimal from django.contrib import admin from .models import Book def apply_discount(modeladmin, request, queryset): for book in queryset: book.price = book.price * decimal.Decimal('0.9') book.save() apply_discount.short_description = 'Apply 10%% discount' class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] actions = [apply_discount, ] # <-- Add the list action function here admin.site.register(Book, BookAdmin)Don’t forget to add the name of the function to the actions list, and the result will be something like this:

Tip!
You can optimize the apply_discount function using a F() expression:
from django.db.models import F def apply_discount(modeladmin, request, queryset): queryset.update(price=F('price') * decimal.Decimal('0.9'))
If you want to learn more about F() expressions, I have a post dedicated to that subject: Django Tips #13 Using F() Expressions
Export to CSV ExampleYou can also use the list action to return a HttpResponse . A simple export to CSV example:
admin.py import decimal, csv from django.contrib import admin from django.http import HttpResponse from django.db.models import F from .models import Book def apply_discount(modeladmin, request, queryset): queryset.update(price=F('price') * decimal.Decimal('0.9')) apply_discount.short_description = 'Apply 10%% discount' def export_books(modeladmin, request, queryset): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="books.csv"' writer = csv.writer(response) writer.writerow(['Title', 'Publication Date', 'Author', 'Price', 'Pages', 'Book Type']) books = queryset.values_list('title', 'publication_date', 'author', 'price', 'pages', 'book_type') for book in books: writer.writerow(book) return response export_books.short_description = 'Export to csv' class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] actions = [apply_discount, export_books, ] admin.site.register(Book, BookAdmin)You can read more about data export here in the blog:
How to Export to Excel Package of the Week: django-import-export List Action as Model Admin MethodAn alternative way to implement it is by creating the list action function as a method of the admin class:
class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] actions = ['apply_discount', export_books] def apply_discount(self, request, queryset): queryset.update(price=F('price') * decimal.Decimal('0.9')) apply_discount.short_description = 'Apply 10%% discount'Pass the method name as a string to the actions list, and rename the modeladmin keyword argument to self .
ConclusionsThere is much more you can do with the admin list actions. Read more in the official documentation .
The example used in this tutorial is available on GitHub: sibtc/django-admin-list-actions