¿Cómo crear y usar señales en Django?

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.

  1. pre_save/post_save : esta señal funciona antes/después del método save().
  2. 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.
  3. 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 crear un proyecto básico usando MVT en Django?

       ¿Cómo crear 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)

Publicación traducida automáticamente

Artículo escrito por kt7756294 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *