Cara Membuat Django Admin List Actions

Bagus Aji Santoso 2 Februari 2018

Cara Membuat Django Admin List Actions

Artikel ini merupakan terjemahan tutorial How to Create Django Admin List Actions bagian ketiga yang ditulis oleh Vitor Freitasl.

Level menengah/intermediate. Pembaca diasumsikan sudah mengerti proses pembuatan aplikasi web menggunakan Django.

Django Admin list action dibuat untuk melakukan operasi ke banyak data sekaligus. Semua list di dalam Django Admin sudah memiliki satu aksi bawaan yaitu "Delete selected ". Di tutorial singkat ini penulis akan membantu pembaca bagaimana cara membuat list action di Django Admin.

Membuat Action Function

Setiap aksi yang ada di dalam list tersebut merupakan fungsi Python biasa yang meminta tiga parameter, ModelAdmin, objek HttpRequest (mirip dengan fungsi view) dan sebuah QuerySet yang berisi daftar instance model yang terpilih.

Action Function bisa disimpan di dalam modul admin.py. Tapi, jika isinya mulai banyak, bisa dipindah keluar file admin.py.

Berikut ini kerangka sebuah Action Function:

def my_admin_action(modeladmin, request, queryset):
    # lakukan sesuatu dengan queryset

my_admin_action.short_description = 'My admin action'

Contoh Sederhana

Perhatikan model dan model admin berikut:

models.py

from 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)

Anggap kita ingin membuat sebuah list action yang akan memberikan diskon 10% ke buku yang terpilih. Kita bisa menulisnya seperti ini:

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)

Jangan lupa untuk menambah nama fungsi ke dalam list actions, dan hasilnya akan terlihat sebagai berikut:

Custom List Action

Tips!

Kita bisa mengoptimalkan fungsi apply_discount dengan memanggil F():

from django.db.models import F

def apply_discount(modeladmin, request, queryset):
    queryset.update(price=F('price') * decimal.Decimal('0.9'))

Jika ingin tahu lebih jauh tentang ekspresi F(), silahkan baca tulisan berikut: Django Tips #13 Using F() Expressions

Contoh Export to CSV

Kita juga bisa membuat list action untuk mengembalikan sebuah HttpResponse. Misalnya kita ingin membuat fitur export to CSV sederhana:

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)

Untuk memahami bagaimana melakukan ekspor data di Django, silahkan baca lagi artikel berikut:

List Action Sebagai Method Model Admin

Alternatif lain untuk membuat action function adalah dengan menambah method di dalam kelas admin:

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'

Kirim nama method sebagai string di dalam list actions, dan ubah argumen modeladmin menjadi self.

Kesimpulan

Ada banyak hal lain yang bisa kita lakukan dengan admin list action. Baca dokumentasi resminya untuk hal lain yang bisa kita lakukan.

Contoh di tutorial ini bisa pembaca lihat di Github: sibtc/django-admin-list-actions