Django Tutorial
Django Create A Complete Project
Django Template
Django Database Query
Django Form
Django Authentication and Permission Management
Django unittest
Django Advanced
Django's signal mechanism follows the Observer design pattern, allowing components to be loosely coupled by sending and receiving messages (signals) between them. When an event occurs in your application, you can send a signal, and any connected signal handlers will be executed.
In this tutorial, we will go through the process of sending and receiving signals in a Django application.
user_logged_in
:from django.dispatch import Signal user_logged_in = Signal(providing_args=["user"])
providing_args
is a list of arguments that the signal will send to connected signal handlers. In this case, we will send the user
object.
@receiver
decorator to connect the signal handler to the signal. For example:from django.dispatch import receiver from .signals import user_logged_in @receiver(user_logged_in) def user_logged_in_handler(sender, user, **kwargs): print(f"User {user} has logged in.")
The signal handler function should accept the sender (the object that sent the signal), the signal arguments (in this case, user
), and any additional keyword arguments.
apps.py
file so they are registered when the application starts:from django.apps import AppConfig class MyAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'myapp' def ready(self): import myapp.signals
user_logged_in
signal when a user logs in through a custom view:from django.contrib.auth import authenticate, login from django.http import HttpResponse from myapp.signals import user_logged_in def custom_login(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) user_logged_in.send(sender=user.__class__, user=user) return HttpResponse("Logged in successfully.") else: return HttpResponse("Invalid credentials.") # Render login form for GET requests
In this example, when a user logs in, the user_logged_in
signal is sent using the send
method, with the sender
and user
arguments. Connected signal handlers (in this case, user_logged_in_handler
) will be executed.
By following these steps, you can use Django's signal mechanism to create a more modular application architecture. Components can react to events without directly referencing each other, improving maintainability and flexibility.
Django Signal Execution Process:
# signals.py from django.db.models.signals import Signal from django.dispatch import receiver my_signal = Signal() # receivers.py @receiver(my_signal) def my_signal_handler(sender, **kwargs): print("Signal received!")
Django Signal Dispatching Process:
# sender.py my_signal.send(sender="SenderObject")
Django Signal Handler Execution Order:
@receiver
decorator's dispatch_uid
parameter.# receivers.py @receiver(my_signal, dispatch_uid="first_handler") def first_handler(sender, **kwargs): print("First handler executed!") @receiver(my_signal, dispatch_uid="second_handler") def second_handler(sender, **kwargs): print("Second handler executed!")
Django Signal Execution Timing:
# some_module.py my_signal.send(sender="SomeObject")
Django Signal Connection and Dispatching:
@receiver
decorator to connect receivers to signals. Dispatching is the process of emitting a signal.# receivers.py @receiver(my_signal) def my_signal_handler(sender, **kwargs): print("Signal received!") # sender.py my_signal.send(sender="SenderObject")