Las señales se utilizan para realizar cualquier acción en la modificación de una instancia de modelo. Las señales son utilidades que nos ayudan a conectar eventos con acciones. Podemos desarrollar una función que se ejecutará cuando una señal la llame. En otras palabras, las señales se utilizan para realizar alguna acción sobre la modificación/creación de una entrada particular en la base de datos. Por ejemplo, uno querría crear una instancia de perfil, tan pronto como se cree una nueva instancia de usuario en la base de datos
Hay 3 tipos de señal.
- pre_save/post_save : esta señal funciona antes/después del método save().
- pre_delete/post_delete : esta señal funciona antes de eliminar la instancia de un modelo (método delete()) y se lanza esta señal.
- pre_init/post_init : esta señal se lanza antes/después de instanciar un modelo (método __init__()).
Consulte los siguientes artículos para comprobar cómo crear un proyecto y una aplicación en Django.
¿Cómo usar Signals ion Django?
Por ejemplo, si queremos crear un perfil de un usuario tan pronto como se crea el usuario usando la señal post_save
Modelos.py
Python3
from django.db import models from django.contrib.auth.models import User from PIL import Image class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) image = models.ImageField(default='default.jpg', upload_to='profile_pics') def __str__(self): return f'{self.user.username} Profile'
Vistas.py
Python3
from django.shortcuts import render, redirect from django.contrib import messages from django.contrib.auth.decorators import login_required from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm def register(request): if request.method == 'POST': form = UserRegisterForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') messages.success(request, f'Your account has been created! You are now able to log in') return redirect('login') else: form = UserRegisterForm() return render(request, 'users/register.html', {'form': form}) @login_required def profile(request): if request.method == 'POST': u_form = UserUpdateForm(request.POST, instance=request.user) p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile) if u_form.is_valid() and p_form.is_valid(): u_form.save() p_form.save() messages.success(request, f'Your account has been updated!') return redirect('profile') else: u_form = UserUpdateForm(instance=request.user) p_form = ProfileUpdateForm(instance=request.user.profile) context = { 'u_form': u_form, 'p_form': p_form } return render(request, 'users/profile.html', context)
Formularios.py
Python3
from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm from .models import Profile class UserRegisterForm(UserCreationForm): email = forms.EmailField() class Meta: model = User fields = ['username', 'email', 'password1', 'password2'] class UserUpdateForm(forms.ModelForm): email = forms.EmailField() class Meta: model = User fields = ['username', 'email'] class ProfileUpdateForm(forms.ModelForm): class Meta: model = Profile fields = ['image']
Signals.py (usando el método del receptor)
Python3
# code from django.db.models.signals import post_save, pre_delete from django.contrib.auth.models import User from django.dispatch import receiver from .models import Profile @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_profile(sender, instance, **kwargs): instance.profile.save()
Puede confundirse con este fragmento de código si es nuevo en Django. Entonces, lo que sucede es que cuando se guarda el modelo de usuario, se activa una señal llamada create_profile que crea una instancia de perfil con una clave externa que apunta a la instancia del usuario. . El otro método save_profile solo guarda la instancia.
Ahora entendamos los argumentos.
- receptor : la función que recibe la señal y hace algo.
- remitente – Envía la señal
- created — Comprueba si el modelo está creado o no
- instancia — instancia del modelo creado
- **kwargs : argumentos de palabras clave comodín
Otra forma de conectar la señal con la función:
Debe conectar el archivo de señales con la función de preparación de archivos app.py para poder usarlos.
Python3
from django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' def ready(self): import users.signals
Aquí la señal vive.
Si creamos un usuario
Entonces su perfil se crea automáticamente.
También puede verificarlo en la vista de administrador
pre_save usando el método del receptor –
El método Pre_save se activa justo antes de que se llame a la función Guardar. Además, el modelo se guarda solo después de la ejecución exitosa del método Pre_Save.
Python3
# code from django.db.models.signals import post_save, pre_delete,pre_save from django.contrib.auth.models import User from django.dispatch import receiver from .models import Profile @receiver(pre_save, sender=User) def checker(sender, instance, **kwargs): if instance.id is None: pass else: current=instance previous=User.objects.get(id=instance.id) if previous.reaction!= current.reaction: #save method can be called
Usamos esto si se cambia la reacción.
Uso de señales Método de conexión
La forma alternativa del método anterior es usar el método de conexión para disparar señales.
Si solo usa post_save.connect (my_function), se activará tan pronto como se active cualquier método de guardado.
post_save.connect(my_function_post_save, sender=MyModel) pre_save.connect(my_function, sender= UserTextMessage)