Rekap Part 2: Menambahkan fungsionalitas admin dan form pada blog
Di tulisan rekap ini akan merangkum tulisan-tulisan sebelumnya:
- Membuat superuser
- Menampikan fitur-fitur blog di admin
- Menyesuaikan tampilan
- Membuat grup level user moderator dan creator
- Manipulasi admin berdasarkan group user
- Membuat custom field di form berdasarkan group user
Membuat Superuser
python manage.py createsuperuser
Lalu ikuti promp yang dimunculkan di terminal
Menampikan fitur-fitur blog di admin
Buka admin.py di folder blog, lalu tambahkan kode berikut
from django.contrib import admin from blog.models import Category, Content, Tags admin.site.register(Category) admin.site.register(Tags) @admin.register(Content) class ContentAdmin(admin.ModelAdmin): pass
Perhatikan hanya content saja yang kita buat dengan class karena di content ini lah kita akan banyak bermain
Saya akan menggunakan aturan yang dibuat di tulisan sebelumnya termasuk forms.py
#forms.py from django import forms from blog.models import Content class ContentForm(forms.ModelForm): OPTIONS = ((False, "Draft"), (True, "Publish")) publish = forms.ChoiceField(choices=OPTIONS) class Meta: model = Content exclude = ("slug",)
Dan di admin juga isinya mengikuti tulisan sebelumnya
@admin.register(Content) class ContentAdmin(admin.ModelAdmin): form = ContentForm list_display = ["title", "slug", "category"] list_display_links = ["title"] search_fields = ["title"] list_filter = ["category"] list_per_page = 10 readonly_fields = ["slug"] fieldsets = ( ("Primary", {"fields": ("title",)}), ("Secondary", {"fields": ("category", "tags", "publish")}), (None, {"fields": ("body",)}), ) def save_model(self, request, obj, form, change): if obj.id is None: title = obj.title obj.slug = title.lower().replace(" ", "-") obj.created_by = request.user super(ContentAdmin, self).save_model(request, obj, form, change)
Setelah superuser dibuat mari buat dua role “creator” dan “moderator”, hak aksesnya mirip dulu, untuk permission yang lain akan dibuat secara “custom” dengan cara mengubah beberapa method bawaan di admin.
Mari buat aturannya:
- Untuk group creator dia hanya bisa lihat postingan punya dia
- Untuk group moderator bisa semua lihat
- Untuk group moderator bisa akses category dan tags
Untuk mendaftarkan user bisa dengan menambahkan secara manual di menu users
setelah itu mari tambahkan dulu field untuk menampung info user di content
#tambahkan baris ini from django.contrib.auth.models import User class Content(models.Model): title = models.CharField(max_length=100) slug = models.CharField(max_length=200, null=True) category = models.ForeignKey( Category, related_name="content", on_delete=models.CASCADE ) tags = models.ManyToManyField(Tags, related_name="content") body = models.TextField() publish = models.BooleanField(default=False) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) #tambah yang baru ini created_by = models.ForeignKey( User, on_delete=models.CASCADE, related_name="content", null=True, blank=True, ) def __str__(self): return self.title
Selanjutnya lakukan lagi makemigrations dan migrate
Setelah menambahkan kolom baru untuk menampung created by selanjutnya adalah bagaiaman django admin mengambil informasi user yang login, saya menggunakan contoh super user dulu (user id= 1 di dalam contoh ini)
Di bagian admin ada method save_model yang saat ini digunakan untuk mengisi nilai slug, untuk mengisi nilai user yang login kita bisa tambahkan di method ini, pertanyaanya bagaimana kita tahu user yang login? Jawabanya sederhana, objek user login terdapat di request, jadi method save_model kita ubah
def save_model(self, request, obj, form, change): if obj.id is None: title = obj.title obj.slug = title.lower().replace(" ", "-") #tambahkan ini obj.created_by = request.user super(ContentAdmin, self).save_model(request, obj, form, change)
Kalau kita membuat konten maka nanti user id akan otomatis terpasang
Membuat group dan user bisa lihat tulisannya di sini
Limitation by group
Sebelumnya saya sudah menyiapkan dummy data agar mempunyai banyak data
Saat login sebagai moderator dia melihat semua postingan, tapi ketika masuk sebagai creator dia hanya lihat punya dia sendiri
Jika untuk manipulasi proses simpan, untuk menampilkan bisa dengan method queryset
def get_queryset(self, request): qs = super().get_queryset(request) user = request.user if user.groups.filter(name="Creator").exists(): return qs.filter(created_by=user) return qs
Kode di atas itu secara default akan menampilkan semuanya, tapi ketika user login terdaftar di group Creator maka hanya akan ditampilkan punya dia sendiri
Validation
Saya ingin yang punya akses ke field publish itu hanya moderator, sehingga content bisa dimoderasi dulu sebelum publish, tapi berhubung di permission hanya ada level form saja (change/edit) maka kita harus effort sedikit, caranya mirip dengan yang query set tapi sekarang diubah adlah fieldsetnya
def get_fieldsets(self, request, obj=None): fieldsets = super().get_fieldsets(request, obj) user = request.user if user.groups.filter(name="Creator").exists(): fieldsets[1][1]["fields"] = ("category", "tags") else: fieldsets[1][1]["fields"] = ("category", "tags", "publish") return fieldsets
Oke selesai, sekarang sat “creator” dan “moderator” login masing-masing akan tampilan yang menyesuaikan.