Tindakan admin¶
Alir kerja dasar dari admin Django adalah, dalam kulit kacang, "pilih sebuah obyek, kemudian rubah itu." Ini bekerja baik untuk kebanyakan penggunaan kasus. Bagaimanapun, jika anda butuh perubahan sama ke banyak obyek sekali waktu, alir kerja ini bisa sangat membosankan.
Di kasus-kasus ini, admin Django membiarkan anda menulis dan mendaftar "actions" -- fungsi sederhana yang dipanggil dengan daftar dari obyek-obyek terpilih pada halaman daftar rubah.
Jika anda mencari daftar perubahan apapun di admin, anda akan melihat fitur ini di tindakan; Django dikirim dengan tindakan "menghapus obyek terpilih" tersedia untuk semua model. Sebagai contoh, ini adalah modul pengguna dari aplikasi django.contrib.auth
pasang-tetap Django :

Peringatan
Tindakan "hapus obyek-obyek terpilih" menggunakan QuerySet.delete()
untuk alasan efesiensi, yang mempunyai surat keberatan yang penting: metode delete()
model anda tidak akan dipanggil.
Jika anda berharap untuk menimpa perilaku ini, cukup tulis sebuah tindakan penyesuaian yang menyelesaikan penghapus di cara yang dipilih -- sebagai contoh, dengan memanggil Model.delete()
untuk setiap dari barang terpilih.
Untuk latar belakang lebih pada penghapusan jumlah besar, lihat dokumentasi pada object deletion.
Baca untuk menemukan bagaimana menambah tindakan anda sendiri ke daftar ini.
Menulis tindakan¶
Cara mudah untukmenjelaskan tindakan adalah dengan contoh, jadi mari kita selami.
Penggunaan kasus umum untuk tindakan admin adalah memperbaharui dalam jumlah besar dari sebuah model. Bayangkan aplikasi berita sederhana dengan model Article
:
from django.db import models
STATUS_CHOICES = (
('d', 'Draft'),
('p', 'Published'),
('w', 'Withdrawn'),
)
class Article(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
status = models.CharField(max_length=1, choices=STATUS_CHOICES)
def __str__(self):
return self.title
Tugas utama kami mungkin lakukan dengan sebuah model seperti ini adalah memperbaharui sebuah keadaan article dari "draft" menjadi "published". Kami dapat dengan mudah melakukan ini di admin satu artikel pada sekali waktu, tetapi jika kami ingin menerbitkan-jumlah besar kelompok dari artikel, itu akan membosankan. Jadi, mari kita menulis sebuah tindakan yang membuat kita merubah sebuah keadaan artikel menjadi "published."
Menulis fungsi tindakan¶
Pertama, kami akan butuh menulis sebuah fungsi yang dipanggil ketika tindakan dipicu dari admin. Tindakan berbagi fungsi hanya fungsi biasa yang mengambil tiga argumen:
ModelAdmin
saat ini- Sebuah
HttpRequest
mewakili permintaan saat ini, - Sebuah
QuerySet
mengandung sekumpulan dari obyek-obyek terpilih oleh pengguna.
Fungsi terbitan-artikel-ini kami tidak butuh ModelAdmin
atau obyek permintaan, tetapi kami akan menggunakan queryset:
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
Catatan
Untuk penampilan terbaik, kami sedang menggunakan update method queryset. Jenis-jenis lain dari tindakan mungkin butuh berurusan dengan setiap obyek pribadi; di kasus-kasus ini kami hanya cukup berulang terhadap queryset:
for obj in queryset:
do_something_with(obj)
Itu benar-benar semuanya ada adalah menulis sebuah tindakan! Bagaimanapun, kami akan mengambil satu atau lebih langkah pilihan-tetapi-berguna dan memberikan tindakan sebuah judul "nice" dalam admin. Secara awalan, tindakan ini akan muncul dalam daftar tindakan sebagai "Make published" -- nama fungsi, dengan garis bawah diganti oleh ruang. Tidak apa-apa, tetai kami dapat menyediakan lebih baik, nama lebih ramah-manusia dengan memberikan fungsi make_published` sebuah atribut short_description
:
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
make_published.short_description = "Mark selected stories as published"
Catatan
Ini mungkin terlihat akrab; pilihan list_display
admin menggunakan teknik sama untuk menyediakan gambaran dapat dibaca-manusia untuk fungsi callback terdaftar disana, juga.
Menambahkan tindakan pada ModelAdmin
¶
Selanjutnya, kami akan butuh menginformasikan ModelAdmin
kami dari tindakan. Ini bekerja seperti piliha konfigurasi lain apapun. Jadi, admin.py
lengkap dengan tindakan dan pendaftarannya akan terlihat seperti:
from django.contrib import admin
from myapp.models import Article
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
make_published.short_description = "Mark selected stories as published"
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'status']
ordering = ['title']
actions = [make_published]
admin.site.register(Article, ArticleAdmin)
Kode akan memberikan kami sebuah daftar rubah admin yang terlihat sesuatu seperti ini:

Itu benar-benar semua yang ada untuk itu! Jika anda sedang gatal menulis tindakan anda sendiri, anda sekarang cukup mengetahui untuk memulai. Sisanya dari dokumen ini hanya mencangkup teknik-teknik lebih lanjut.
Penanganan kesalahan di tindakan¶
Jika ada kondisi kesalahan mendatang yang mungkin muncul selagi menjalankan tindakan anda, anda harus anggun menginformasikan pengguna dari masalah. Ini berarti menangani pengecualian dan menggunakan django.contrib.admin.ModelAdmin.message_user()
untuk memperlihatkan gambaran yang ramah pengguna dari masalah di tanggapan.
Teknik-teknik tindakan lanjutan¶
Ada sepasang pilihan tambahan dan kemungkinan anda dapat menggunakan lebih pilihan lanjutan
Tindakan sebagai metode ModelAdmin
¶
Contoh diatas menunjukkan tindakan make_published
ditentukan sebagai sebuah fungsi sederhana. Itu sangat baik, tetapi itu tidak sempurna dari titik rancangan kode dari tampilan: sejak tindakan erat digabungkan ke obyek Article
, itu masuk akal mengkaitkan tindakan ke obyek ArticleAdmin
itu sendiri.
Itu cukup mudah melakukan:
class ArticleAdmin(admin.ModelAdmin):
...
actions = ['make_published']
def make_published(self, request, queryset):
queryset.update(status='p')
make_published.short_description = "Mark selected stories as published"
Perhatikan pertama yang kami telah pindahkan make_published
kedalam metode dan dinamai kembali parameter modeladmin
pada self
, dan kedua kami telah sekarang menaruh string 'make_published'
dalam actions
daripada acuan fungsi langsung. Ini mengatakan ModelAdmin
untuk mencari tindakan sebagai sebuah metode.
Menentukan tindakan sebagai metode memberikan tindakan lebih mudah, akses idiomatis ke ModelAdmin
itu sendiri, mengizinkan tindakan memanggil metode apapun disediakan oleh admin.
Sebagai contoh, kami dapat menggunakan self
pada sebuah pesan sekejab ke pengguna menginformasikan dia bahwa tindakan telah berhasil:
class ArticleAdmin(admin.ModelAdmin):
...
def make_published(self, request, queryset):
rows_updated = queryset.update(status='p')
if rows_updated == 1:
message_bit = "1 story was"
else:
message_bit = "%s stories were" % rows_updated
self.message_user(request, "%s successfully marked as published." % message_bit)
Ini membuat tindakan cocok apa yang admin itu sendiri lakukan setelah berhasil melakukan sebuah tindakan:

Tindakan yang menyediakan halaman menengah¶
Secara awalan, setelah sebuah tindakan dilakukan pengguna cukup mengalihkan kembali kehalaman daftar rubah asli. Bagaimanapun, beberapa tindakan, khususnya satu lebih rumit, akan butuh mengembalikan halaman menengah. Sebagai contoh, tindakan hapus siap-pakai meminta untuk penegasan sebelum menghapus obyek-obyek terpilih
Untuk menyediakan sebuah halaman menengah, cukup kembalikan sebuah HttpResponse
(atau subkelas) dari tindakan anda. Sebagai contoh, anda mungkin menulis sebuah fungsi ekspor sederhana yang menggunakan serialization functions Django unutk membuang beberapa obyek-obyek terpilih sebagai JSON:
from django.core import serializers
from django.http import HttpResponse
def export_as_json(modeladmin, request, queryset):
response = HttpResponse(content_type="application/json")
serializers.serialize("json", queryset, stream=response)
return response
Umumnya, sesuatu seperti diatas tidak dianggap ide yang hebat. Kebanyakan dari waktu, praktik terbaik akan mengembalikan sebuah HttpResponseRedirect
dan pengalihan pengguna ke sebuah tamilan anda telah tulis, melewatkan daftar dari obyek-obyek terpilih di string permintaan GET. Ini mengizinkan anda menyediakan logika interaksi rumit pada halaman penengah. Sebagai contoh, jika anda ingin menyediakan fungsi ekspor lebih rumit, anda ingin membiarkan penggua memilih bentuk, dan kemungkinan daftar dari bidang-bidang untuk disertakan di export. Hal terbaik untuk melakukan adalah menulis tindakan kecil yang cukup mengalihkan tampilan ekspor penyesuaian anda:
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponseRedirect
def export_selected_objects(modeladmin, request, queryset):
selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
ct = ContentType.objects.get_for_model(queryset.model)
return HttpResponseRedirect("/export/?ct=%s&ids=%s" % (ct.pk, ",".join(selected)))
Seperti anda dapat lihat, tindakan adalah bagian sederhana; semua logika rumit akan milik di tampilan ekspor anda. Ini akan butuh berurusan dengan obyek-obyek dari jenis apapun, dengan demikian bisnis dengan ContentType
.
Meunlis tampilan ini adalah sisa dari sebuah latihan ke pembaca.
Membuat tindakan tersedia lebar-situs¶
-
AdminSite.
add_action
(action, name=None)[sumber]¶ Beberapa tindakan adalah terbaik jika mereka membuat tersedia pada setiap obyek di situs admin -- tindakan ekspor ditentukan diatas akan menjadi calon bagus. Anda dapat membuat sebuah tindakan secara global tersedia menggunakan
AdminSite.add_action()
. Sebagai contoh:from django.contrib import admin admin.site.add_action(export_selected_objects)
Ini membuat tindakan
export_selected_objects
secara global tersedia sebagai sebuah tindakan bernama "export_selected_objects". Anda dapat dengan jelas memberikan tindakan sebuah nama -- bagus jika anda kemudian ingin secara program remove the action -- dengan melewatkan argumen kedua keAdminSite.add_action()
:admin.site.add_action(export_selected_objects, 'export_selected')
Meniadakan tindakan¶
Terkadang anda butuh meniadakan beberapa tindakan -- khususnya itu registered site-wide -- untuk obyek-obyek tertentu. Ada sedikit cara anda dapat meniadakan tindakan:
Meniadakan tindakan lebar-situs¶
-
AdminSite.
disable_action
(name)[sumber]¶ Jika anda butuh meniadakan sebuah site-wide action anda dapat memanggil
AdminSite.disable_action()
.Sebagai contoh, anda dapat menggunakan metode ini memindahkan tindakan "delete selected objects" siap-pakai:
admin.site.disable_action('delete_selected')
Sekali anda telah melakukan diatas, tindakan itu akan tidak lagi tersedia lebar-situs.
Jika, bagaimanapun, anda butuh mengadakan kembali tindakan ditiadakan-global untuk satu model tertentu, cukup daftar itu dengan jelas di daftar
ModelAdmin.actions
anda:# Globally disable delete selected admin.site.disable_action('delete_selected') # This ModelAdmin will not have delete_selected available class SomeModelAdmin(admin.ModelAdmin): actions = ['some_other_action'] ... # This one will class AnotherModelAdmin(admin.ModelAdmin): actions = ['delete_selected', 'a_third_action'] ...
Meniadakan semua tindakan untuk ModelAdmin
tertentu¶
Jika anda ingin tidak tindakan dalam jumlah besar tersedia untuk ModelAdmin
yang diberikan, cukup setel ModelAdmin.actions
menjadi None
:
class MyModelAdmin(admin.ModelAdmin):
actions = None
Ini memberitahu ModelAdmin
untuk tidak memperlihatkan atau mengizinkan tindakan apapun, termasuk site-wide actions apapun.
Tindakan mengadakan dan meniadakan bersyarat¶
-
ModelAdmin.
get_actions
(request)[sumber]¶ Akhirnya, anda dapat secara kondisional mengadakan atau meniadakan tindakan-tindakan pada sebuah per-permintaan (dan karenanya berdasarkan per-pengguna) dengan mengutamakan
ModelAdmin.get_actions()
.Ini mengembalikan sebuah kamus dari tindakan diizinkan. Kunci-kunci adalah nama-nama tindkan, dan nilai-nilai adalah tuple
(function, name, short_description)
.Kebanyakan waktu anda akan menggunakan metode ini secara kondisional memintahkan tindakan-tindakan dari daftar dikumpulkan oleh superkelas. Sebagai contoh, jika Saya hanya menginginkan pengguna-pengguna yang nama-namanya dimulai dengan 'J' untuk dapat menghapus obyek-obyek dalam jumlah besar, Saya dapat melakukan berikut:
class MyModelAdmin(admin.ModelAdmin): ... def get_actions(self, request): actions = super().get_actions(request) if request.user.username[0].upper() != 'J': if 'delete_selected' in actions: del actions['delete_selected'] return actions