Files
api/app/signals.py
anhduy-tech f76cd880e1 changes
2026-03-19 11:57:52 +07:00

82 lines
2.7 KiB
Python

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.apps import apps
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from django.db import transaction
from .views import get_serializer
MODELS_TO_IGNORE = ['LogEntry', 'Session', 'ContentType', 'AdminLog', 'Permission', 'Group', 'Token', 'Phone_Otp']
def send_model_update(instance, change_type):
"""
Hàm chung để gửi cập nhật model qua WebSocket.
"""
model_class = instance.__class__
model_name = model_class._meta.model_name
if model_class.__name__ in MODELS_TO_IGNORE:
return
_model, serializer_class = get_serializer(model_name)
if not serializer_class:
print(f"Warning: No serializer found for model {model_name}. Cannot send update.")
return
serializer = serializer_class(instance)
payload = {
"name": model_name,
"change_type": change_type,
"record": serializer.data
}
channel_layer = get_channel_layer()
group_name = f"model_{model_name}_updates"
async_to_sync(channel_layer.group_send)(
group_name,
{
"type": "realtime.update",
"payload": payload
}
)
def generic_post_save_handler(sender, instance, created, **kwargs):
"""
Hàm xử lý chung cho tín hiệu post_save từ BẤT KỲ model nào.
"""
def send_update_after_commit():
change_type = "created" if created else "updated"
try:
refreshed_instance = sender.objects.get(pk=instance.pk)
send_model_update(refreshed_instance, change_type)
except sender.DoesNotExist:
print(f"Object {sender.__name__} {instance.pk} đã bị xóa, bỏ qua gửi update.")
send_model_update(instance, "deleted")
except Exception as exc:
print(f"Lỗi trong send_update_after_commit: {exc}")
transaction.on_commit(send_update_after_commit)
def generic_post_delete_handler(sender, instance, **kwargs):
"""
Hàm xử lý chung cho tín hiệu post_delete từ BẤT KỲ model nào.
"""
def send_delete_after_commit():
send_model_update(instance, "deleted")
transaction.on_commit(send_delete_after_commit)
def connect_signals():
"""
Kết nối các hàm xử lý chung với tín hiệu post_save và post_delete.
Không chỉ định `sender` để lắng nghe tất cả các model.
"""
post_save.connect(generic_post_save_handler, dispatch_uid="generic_post_save")
post_delete.connect(generic_post_delete_handler, dispatch_uid="generic_post_delete")
print("Connected generic signals for real-time updates.")