Skillversitas

Signals

The signal is the event the hook: the 5 (the pre_save, the post_save, the m2m_changed, the pre_migrate, the request_started), the receiver (the 1, the no the code), and the no is the magic (the explicit, the no the no). The connect is the 1 (the apps.py, the 1st the 1, the no the no), the sender is the filter (the 1 the model, the no the 1), and the transaction is the no (the no the no, the no the 1). This chapter covers the 5 (the no the 1, the no the the), the @receiver (the 1, the no the code), the connect (the apps.py, the 1st), and the no (the magic, the explicit the 1).

The 5 signal and the receiver

# the 5 (the no 1, the no the
#   the, the no the no):
#   the 1: the pre_save (the no,
#     the 1, the no
#     the no, the no
#     the change):
#   the 2: the post_save (the no,
#     the no, the no
#     the no, the 1 the
#     the no):
#   the 3: the m2m_changed (the
#     the 2, the no
#     the no, the no
#     the no):
#   the 4: the pre_migrate (the
#     the no, the no
#     the no, the no
#     the no):
#   the 5: the request_started
#     (the 1, the no
#     the no, the no
#     the no):
from django.db.models.signals import (
    pre_save, post_save,
    m2m_changed)
from django.core.signals import \
    request_started
from django.dispatch import receiver
from .models import Note, Tag

#   the RECEIVER (the 1, the no
#     the code, the sender's):
@receiver(pre_save, sender=Note)
def note_pre_save(sender, instance,
    **kwargs):
    #   the no: the 1 (the no,
    #     the no, the no
    #     the no, the no
    #     the change):
    if not instance.slug:
        instance.slug = slugify(
            instance.title)
    #   the no: the no (the no,
    #     the no, the no
    #     the no)

@receiver(post_save, sender=Note)
def note_post_save(sender, instance,
    created, **kwargs):
    #   the no: the 1 (the no,
    #     the no, the no
    #     the no):
    cache.delete("notes:all")
    if created:
        #   the no: the no (the
        #     the no, the no
        #     the no, the no
        #     the no):
        logger.info(
            "note created: %s",
            instance.pk)

@receiver(m2m_changed,
    sender=Note.tags.through)
def note_tags_changed(sender, instance,
    action, pk_set, **kwargs):
    #   the no: the 2 (the no,
    #     the no, the no
    #     the no):
    cache.delete(f"note:{instance.pk}")
    #   the no: the no (the
    #     the no, the no
    #     the no, the no
    #     the no)

The 5 is the no the 1: the pre_save (the no, the 1, the change the no the 1, the slug the 1), the post_save (the no, the created the 1, the cache the delete), the m2m_changed (the action the add the remove, the pk_set, the through the sender), the pre_migrate (the 1, the no the the), and the request_started (the 1, the no the 1) - the @receiver is the 1: the sender is the filter (the Note, the no the 1, the no the the), the instance is the 1 (the no the 1), and the created is the 1 (the post_save only, the no the pre) - the sender is the no (the 1 the 1, the no the no, the no the the), and the connect is the next: the apps.py the 1st the 1.

The connect and the no-magic

# the CONNECT (the apps.py, the
#   1st, the no the no):
#   the notes_app/apps.py:
from django.apps import AppConfig

class NotesAppConfig(AppConfig):
    default_auto_field = \
        "django.db.models." \
        "BigAutoField"
    name = "notes_app"
    #   the no: the 1 (the no,
    #     the no, the no
    #     the no):
    def ready(self):
        #   the 1: the no (the
        #     the no, the no
        #     the no, the no
        #     the no):
        import notes_app.signals
        #   the no: the 1 (the
        #     the no, the no
        #     the no, the no
        #     the no)

#   the no: the no (the 1, the
#     the no, the no
#     the no, the no
#     the no)

# the MANUAL (the no, the 1 the
#   no, the no the no):
from django.dispatch import Signal

note_published = Signal()
#   the send (the no, the 1,
#     the no the no):
def publish_note(note):
    note.published = True
    note.save()
    note_published.send(
        sender=note.__class__,
        note=note)
    #   the no: the no (the
    #     the no, the no
    #     the no, the no
    #     the no)
#   the receive (the 1, the no,
#     the no the no):
@receiver(note_published)
def on_published(sender, note, **kw):
    #   the no: the 1 (the no,
    #     the no, the no
    #     the no, the no
    #     the no):
    cache.delete("notes:published")
    #   the no: the no (the no,
    #     the no, the no
    #     the no)

# the NO-MAGIC (the explicit, the
#   1, the no the no):
#   the no: the 1 (the no,
#     the no, the no
#     the no, the no
#     the no):
#   the no: the no (the no,
#     the no, the no
#     the no, the no
#     the no)
#   the no: the no (the no,
#     the no, the no
#     the no, the no
#     the no)

The connect is the apps.py: the ready() is the 1st the 1 (the import the signals, the no the no, the no the 1), and the 1 is the 1 (the no the no, the no the the, the no the 1) - the 1 is the no (the no the no, the no the no, the no the 1). The manual signal is the 1: the Signal() is the no the built-in (the note_published, the no the 1), the send is the 1 (the sender plus the no, the no the no), and the receiver is the no the sender (the 1, the no the filter, the no the 1) - the no-magic is the explicit: the no is the 1 (the no the no, the no the no, the 1 the no the no), and the rule is the one: the 5 the no the 1, the @receiver the 1, the connect the apps.py, and the no-magic the explicit - the next chapter's DRF is the API the serializer the viewset the no the code.

The Working Rules

  • The 5 is the no 1, the sender the filter. The pre_save the no (the change, the slug), the post_save the created (the cache), and the m2m_changed the action (the add, the remove, the through) - the pre_migrate the 1 (the no the the), and the request_started the 1 (the no the 1), and the no the 1 (the no the no, the no the 1).
  • The @receiver is the 1, the no code. The sender the Note (the no the 1, the no the the), and the instance the 1 (the no the 1) - the created the post_save only (the no the pre), and the kwargs the no (the no the 1, the no the no).
  • The connect is the apps.py, the ready the 1st. The import the signals (the no the no, the no the 1), and the 1 the 1 (the no the no, the no the the) - the no the no (the 1, the no, the no the no), and the no the no (the no the no, the no the no).
  • The manual is the Signal, the send the no. The Signal() the no the built-in (the note_published), and the send the sender plus the no (the no the no) - the receiver the no the sender (the 1, the no the filter), and the no-magic the explicit (the no the no, the no the no).

Summary

The signal is the event the hook: the 5 (the pre_save the no the change, the post_save the created, the m2m_changed the action the through, the pre_migrate the 1, and the request_started the 1), the @receiver the 1 (the sender the filter, the instance the no, the created the post_save only), the connect the apps.py (the ready the 1st the 1, the import the signals, the no the no), and the manual Signal (the no the built-in, the send the sender, the receiver the no the sender). The no-magic is the explicit (the no the no, the no the no, the no the no) - the rule is the one: the 5 the no the 1, the receiver the 1, the connect the apps.py, and the explicit the no the magic. The next chapter's DRF is the API: the serializer the no the model, the viewset the no the code, and the permission the no the 403.