2026-09-07 19:43:48 +03:00

112 lines
4.3 KiB
Python

"""
Django signals для автоматической генерации уведомлений для django-scheduler.
Обрабатывает события:
- post_save для schedule.Event - создание или изменение события
- pre_save для schedule.Event - отслеживание изменений полей
- pre_delete для schedule.Event - отмена (удаление) события
"""
import logging
from django.db.models.signals import post_save, pre_delete, pre_save
from django.dispatch import receiver
logger = logging.getLogger(__name__)
@receiver(post_save, sender="schedule.Event")
def create_event_notifications(sender, instance, created, **kwargs):
"""
Создает уведомления при создании или изменении события.
Уведомления отправляются:
- При создании - всем участникам календаря (через CalendarRelation)
- При изменении - участникам календаря (если изменились важные поля)
"""
from .handlers import notify_event_changed, notify_event_created
try:
if created:
# Получаем создателя события из request (если доступен)
creator = getattr(instance, "_creator", None)
notify_event_created(instance, creator)
else:
# Проверяем изменения
changed_fields = getattr(instance, "_changed_fields", [])
if changed_fields:
modifier = getattr(instance, "_modifier", None)
notify_event_changed(instance, changed_fields, modifier)
except Exception as e:
logger.exception(
"Schedule event notification signal failed",
extra={
"event": "schedule.event.notification_signal_failed",
"schedule_event_id": instance.pk,
"object_created": created,
"error_type": type(e).__name__,
},
)
@receiver(pre_save, sender="schedule.Event")
def track_event_changes(sender, instance, **kwargs):
"""
Отслеживает изменения важных полей события для уведомлений.
Сохраняет список изменённых полей в атрибут _changed_fields,
который затем используется в post_save signal.
"""
from .config import IMPORTANT_FIELDS
if instance.pk:
try:
from schedule.models import Event
old_event = Event.objects.get(pk=instance.pk)
changed_fields = []
# Проверяем изменения важных полей
for field in IMPORTANT_FIELDS:
old_value = getattr(old_event, field, None)
new_value = getattr(instance, field, None)
if old_value != new_value:
changed_fields.append(field)
instance._changed_fields = changed_fields
except Exception as e:
logger.exception(
"Schedule event change tracking failed",
extra={
"event": "schedule.event.change_tracking_failed",
"schedule_event_id": instance.pk,
"error_type": type(e).__name__,
},
)
instance._changed_fields = []
else:
instance._changed_fields = []
@receiver(pre_delete, sender="schedule.Event")
def notify_event_cancelled_signal(sender, instance, **kwargs):
"""
Создает уведомления при удалении (отмене) события.
Уведомления отправляются всем участникам календаря.
"""
from .handlers import notify_event_cancelled
try:
canceller = getattr(instance, "_canceller", None)
notify_event_cancelled(instance, canceller)
except Exception as e:
logger.exception(
"Schedule event cancellation signal failed",
extra={
"event": "schedule.event.cancelled_signal_failed",
"schedule_event_id": instance.pk,
"error_type": type(e).__name__,
},
)