Featured image of post Metadata Model Django (Meta Class, Verbose Names, Ordering, Indexes)

Metadata Model Django (Meta Class, Verbose Names, Ordering, Indexes)

Memahami cara menggunakan Meta class di Django untuk mengatur nama model yang mudah dipahami, urutan data default, dan optimasi query dengan index.

Metadata Model (Meta Class, Verbose Names, Ordering, Indexes)

Sebelumnya kita sudah mempelajari cara mendesain field dan relasi. Kali ini kita akan belajar cara mengontrol bagaimana Django memahami model kita secara keseluruhan. Itulah fungsi dari metadata model.

Di Django, metadata biasanya didefinisikan dalam inner class bernama Meta. Anggap saja ini seperti control panel untuk model kita: class ini tidak menambah field data baru, tapi mengubah perilaku model seperti:

  • bagaimana nama model tampil di web admin Django
  • urutan sorting default
  • optimasi level database lewat index
  • penamaan tabel dan opsi lanjutan lainnya

Kalau field adalah “apa” dari model kita, Meta adalah “bagaimana model ini berperilaku”.


Apa Itu Meta Class?

Di dalam model, kita bisa menulis seperti ini:

1
2
3
4
5
6
class Article(models.Model):
    title = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']

Meta class bukan model terpisah. Ini adalah konfigurasi untuk model yang ada di atasnya.

Kesalahan yang sering terjadi:

  • Mencoba menaruh definisi field di dalam Meta

Di dalam Meta, yang diisi hanya konfigurasi, bukan field data.


Verbose Names (Nama Model yang Lebih Ramah Manusia)

Secara default, Django membuat nama model otomatis dari nama class:

  • Article -> “article”
  • plural -> “articles”

Ini sebenarnya oke, tapi kadang kurang ideal untuk keterbacaan di admin, laporan, atau kejelasan tim dalam beberapa kasus (contoh: Category → Categorys).

Gunakan opsi berikut di Meta:

  • verbose_name
  • verbose_name_plural

Contoh:

1
2
3
4
5
6
class BlogPost(models.Model):
    title = models.CharField(max_length=200)

    class Meta:
        verbose_name = 'Blog Post'
        verbose_name_plural = 'Blog Posts'

Kenapa ini penting:

  • Sidebar Django admin jadi lebih rapi dan profesional
  • Rekan tim non-teknis bisa lebih mudah memahami label
  • Menghindari auto-pluralization yang aneh

Kapan kita sebaiknya set verbose names?

Set ketika:

  • nama model tidak natural saat dibaca
  • bentuk pluralnya aneh atau ambigu
  • kita peduli tampilan admin yang rapi

Jika nama default sudah pas, kita boleh skip.


Default Ordering

ordering di Meta menentukan urutan sort default untuk queryset model tersebut.

Contoh:

1
2
3
4
5
6
class Article(models.Model):
    title = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']

Sekarang query ini:

1
Article.objects.all()

akan otomatis mengembalikan artikel terbaru terlebih dahulu.

Cara membaca ordering syntax

  • 'created_at' artinya ascending (terlama dulu)
  • '-created_at' artinya descending (terbaru dulu)
  • bisa pakai banyak field:
1
2
class Meta:
    ordering = ['status', '-created_at']

Artinya:

  1. Urutkan berdasarkan status dulu
  2. Jika status sama, urutkan berdasarkan created_at terbaru

Hal penting yang perlu diperhatikan

  • Default ordering memengaruhi setiap queryset kecuali di-override.
  • Ordering berlebihan pada dataset besar bisa menurunkan performa.

Kalau perlu, override pada query tertentu:

1
Article.objects.order_by('title')

Itu akan meng-override model default untuk queryset tersebut.


Indexes (Mempercepat Lookup)

Index membantu database menemukan baris data lebih cepat, terutama saat filtering, searching, dan sorting.

Tanpa index, DB bisa melakukan scan ke banyak baris. Dengan indexing yang baik, DB bisa melompat lebih cepat ke data yang relevan.

Single-field index (sederhana)

Kita bisa mendefinisikan index langsung di field:

1
title = models.CharField(max_length=200, db_index=True)

Gunakan ini untuk field yang sering kita pakai untuk filter, seperti:

  • slug
  • status
  • created_at

Composite indexes (beberapa field)

Di dalam Meta, gunakan indexes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from django.db import models

class Article(models.Model):
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    status = models.CharField(max_length=20)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        indexes = [
            models.Index(fields=['status', '-created_at']),
            models.Index(fields=['author', 'status']),
        ]

Dalam kasus apa composite indexes berguna:

  • Jika kita sering query WHERE status='published' ORDER BY created_at DESC, index ['status', '-created_at'] membantu.
  • Jika kita sering query dengan author dan status sekaligus, index kedua membantu.

Contoh query API nyata

Pola queryset DRF yang umum:

1
2
Article.objects.filter(status='published').order_by('-created_at')
Article.objects.filter(author=request.user, status='draft')

Kita perlu menerapkan index berdasarkan pola query sebenarnya, bukan kira-kira.

Trade-off dari index

Index meningkatkan kecepatan baca, tapi ada harga yang harus dibayarkan:

  • write lebih lambat (INSERT/UPDATE/DELETE)
  • storage lebih besar

Jadi: tambahkan index secara intentional, terutama pada field yang memang sering dipakai filter/sort.


Contoh Lengkap Praktis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from django.conf import settings
from django.db import models


class Article(models.Model):
    class Status(models.TextChoices):
        DRAFT = 'draft', 'Draft'
        PUBLISHED = 'published', 'Published'
        ARCHIVED = 'archived', 'Archived'

    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='articles',
    )
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    body = models.TextField()
    status = models.CharField(
        max_length=20,
        choices=Status.choices,
        default=Status.DRAFT,
        db_index=True,
    )
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Article'
        verbose_name_plural = 'Articles'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status', '-created_at']),
            models.Index(fields=['author', 'status']),
        ]

    def __str__(self):
        return self.title

Yang kita dapatkan dari kode ini:

  • Penamaan yang rapi di admin (Article, Articles)
  • Hasil query default terbaru dulu
  • Query API umum lebih cepat berdasarkan status/created_at/author

Hubungan dan Pengaruhnya dengan Serialization

Sebelumnya kita sempat melihat “Bagaimana Relasi Mempengaruhi Serialization”. Metadata juga memengaruhi perilaku API secara tidak langsung:

  • ordering mengubah urutan default dari output queryset, yang berarti urutan response list API juga berubah
  • index yang lebih baik membuat endpoint list lebih cepat
  • penamaan yang jelas meningkatkan maintainability di serializer, views, admin, dan komunikasi tim

Jadi metadata bukan hanya detail database. Ini juga memengaruhi kualitas API dan experience dari developer.


Latihan Praktik

  1. Buat app sandbox baru supaya kita tidak menyentuh app yang sudah ada:
1
python manage.py startapp metadata_lab
  1. Tambahkan 'metadata_lab' ke INSTALLED_APPS di config/settings.py.

  2. Buka metadata_lab/models.py lalu ganti isinya dengan kode ini:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from django.conf import settings
from django.db import models


class MetadataCourse(models.Model):
    instructor = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='metadata_courses_teaching',
    )
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        verbose_name = 'Metadata Course'
        verbose_name_plural = 'Metadata Courses'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['instructor', '-created_at']),
        ]

    def __str__(self):
        return self.title
  1. Simpan file, lalu generate dan apply migration:
1
2
python manage.py makemigrations
python manage.py migrate
  1. Di shell, lakukan test seperti ini:
1
python manage.py shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from django.contrib.auth import get_user_model
from metadata_lab.models import MetadataCourse

User = get_user_model()
u = User.objects.first() or User.objects.create_user(username='meta_user', password='pass12345')

MetadataCourse.objects.create(instructor=u, title='API Metadata Basics', description='Intro')
MetadataCourse.objects.create(instructor=u, title='Index Patterns', description='Composite index example')

MetadataCourse.objects.values_list('title', 'created_at')  # default terbaru dulu dari Meta.ordering
MetadataCourse.objects.order_by('created_at').values_list('title', 'created_at')  # override manual terlama dulu

Kesalahan Yang Sering Terjadi

  • Menambahkan terlalu banyak index “untuk jaga-jaga”
  • Lupa bahwa default ordering memengaruhi setiap queryset
  • Menggunakan Meta untuk field data, bukan konfigurasi
  • Set verbose names tidak konsisten antar model
  • Membuat index sebelum memahami pola query yang sebenarnya

Ringkasan

  • Meta mengontrol perilaku model, bukan data model.
  • verbose_name dan verbose_name_plural memudahkan keterbacaan di admin dan alur kerja tim.
  • ordering menentukan urutan sort default secara global untuk model tersebut.
  • indexes meningkatkan performa query jika selaras dengan pola filter/sort nyata.
  • Metadata yang baik membuat project DRF kita lebih rapi, lebih cepat, dan lebih mudah dirawat.

Foto cover oleh markuswinkler dari Unsplash

Dibawah Lisensi CC BY-NC-SA 4.0
Dibangun dengan Hugo
Tema Stack dirancang oleh Jimmy