Source code for smarter.lib.annotation.receivers

# pylint: disable=unused-argument
"""Django signal receivers of Smarter annotations."""

from django.db import transaction
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver

from smarter.lib import logging
from smarter.lib.django.listview import LISTVIEW_CACHE_ALL, connect_listview_cache
from smarter.lib.django.models import MetaDataModel

from .models import Annotation, get_cached_annotations

logger = logging.getLogger(__name__)
logger_prefix = logging.SmarterFormattedText.text(__name__)


[docs] @receiver(post_delete) def delete_annotations(sender, instance, **kwargs): """ Delete a resource's annotations when the resource is deleted. Annotations point at their resource through a content type, not a foreign key, so the database doesn't cascade the deletion. """ if not isinstance(instance, MetaDataModel) or instance.pk is None: return changes = Annotation.objects.delete_for_object(instance) if changes: logger.debug( "%s.delete_annotations() deleted %s annotations of %s %s", logger_prefix, len(changes), sender.__name__, instance.pk, )
[docs] @receiver(post_save, sender=Annotation, dispatch_uid=f"{__name__}.invalidate_cached_annotations.post_save") @receiver(post_delete, sender=Annotation, dispatch_uid=f"{__name__}.invalidate_cached_annotations.post_delete") def invalidate_cached_annotations(sender, instance: Annotation, **kwargs): """ Make a resource's cached annotations stale when one of its rows is saved or deleted. Rows change through :meth:`~smarter.lib.annotation.models.AnnotationQuerySet.sync`, and also through the Django admin and direct writes, which don't go through it. Waiting for the commit keeps a request that reads the rows before the change commits from caching the old ones. """ content_type_id, object_id = instance.content_type_id, instance.object_id logger.debug( "%s.invalidate_cached_annotations() content_type_id=%s object_id=%s", logger_prefix, content_type_id, object_id, ) transaction.on_commit(lambda: get_cached_annotations.invalidate(content_type_id, object_id))
# the web console's lists show annotations and filter by them, and an annotation may change without # its resource being saved, e.g. with set_annotation() or in the Django admin. connect_listview_cache(LISTVIEW_CACHE_ALL, "annotation.Annotation")