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.")