Dalam banyak kasus ketika Anda melakukan operasi CRUD pada django models, Anda perlu menjalankan beberapa aktivitas. Django memberi Anda cara yang elegan untuk menangani situasi ini dengan menggunakan SIGNAL.

Signal adalah utilitas yang memungkinkan Anda mengaitkan peristiwa dengan aktivitas tertentu. Anda bisa membuat sebuah fungsi yang akan berjalan saat signal dipanggil.

 

Django Built-in Signals

Disini Anda dapat menemukan panduan tentang beberapa Built-in Signals internal django :

Model Signals

django.db.models.signals.pre_init:

receiver_function(sender, *args, **kwargs)

django.db.models.signals.post_init:

receiver_function(sender, instance)

django.db.models.signals.pre_save:

receiver_function(sender, instance, raw, using, update_fields)

django.db.models.signals.post_save:

receiver_function(sender, instance, created, raw, using, update_fields)

django.db.models.signals.pre_delete:

receiver_function(sender, instance, using)

django.db.models.signals.post_delete:

receiver_function(sender, instance, using)

django.db.models.signals.m2m_changed:

receiver_function(sender, instance, action, reverse, model, pk_set, using)
Request/Response Signals

django.core.signals.request_started:

receiver_function(sender, environ)

django.core.signals.request_finished:

receiver_function(sender, environ)

django.core.signals.got_request_exception:

receiver_function(sender, request)

Dokumentasi lengkapnya kamu bisa membacanya di sini : Django signals documentation

Study Kasus

Untuk melakukan audit trail pada aktifitas user, Anda perlu menangkap setiap aktifitas perubahan data yang dilakukan user disebuah table. sebagai contoh Anda mempunyai table product :

CREATE TABLE product (
	id serial NOT NULL,
	product_name varchar(255) NOT NULL,
	price int4 NULL,
	limit_user int4 NULL,
);

tahap selanjutnya, buat sebuah table dengan nama user_history

 

CREATE TABLE user_history (
	id serial NOT NULL,
	model_name varchar(255) NOT NULL,
	activity varchar(255) NOT NULL,
	user_id int4 NOT NULL,
);

Membuat Signal Historical Record

1) Buat middleware get current user login

Pada tutorial sebelumnya kita telah mempelajari bagaimana cara membuat middleware untuk mendapatkan id user saat ini yang sedang login. baca artikel berikut ini : Membuat middleware get username

2)  Buat File signals.py

from django.dispatch import receiver
from apps.models import History, Product
from apps.middleware import get_current_user
 
def historical_record(user_id=None,activity=None,table=None):
    History(
        user_id=user_id,
        activity=activity,
        model_name = table
    ).save()
    return True
 
@receiver(post_save, sender=Product)
def create_product(sender, instance, created, **kwargs):
    user = get_current_user()
    if created:
        historical_record(user.id,"tambah data product (id:{}, name:{})".format(instance.pk,instance.product_name),"Product")
 
@receiver(pre_save, sender=Product)
def update_product(sender, instance, **kwargs):
    user = get_current_user()
    if not instance._state.adding:
        historical_record(user.id,"ubah data product (id:{}, name:{})".format(instance.pk,instance.product_name),"Product")
 
@receiver(post_delete, sender=Product)
def delete_product(sender, instance, **kwargs):
    user = get_current_user()
    historical_record(user.id,"hapus data product (id:{}, name:{})".format(instance.pk,instance.product_name),"Product")

3) Import File signals.py

buka file apps.py pada directory utama apps Anda, perhatikan kode dibawah ini :

from django.apps import AppConfig
 
 
class ProductConfig(AppConfig):
    name = 'product'
    def ready(self):
        import product.signals

4) Auto Run Signal

Agar file signal yang kita buat bisa dalam mode auto run, buka file __init__,py pada directory apps anda, perhatikan kode dibawah ini :

default_app_config = 'product.apps.ProductConfig'

 

Saatnya melakukan uji coba dengan melakukan operasi CRUD pada model product, selamat mencoba 🙂

Baca artikel lainya :