Skip to content
Django
11. Django Files Cheatsheet
Signals

Signals

Signal is a way to communicate between threads. It is a way to send a message to a thread that it should stop what it is doing and do something else.

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
 
@login_required
def profile(request):
    """
    Renders the profile page of the logged-in user.
    """
    return render(request, 'users1/profile.html')
 
@login_required
def edit_profile(request):
    """
    Renders the edit profile page and handles the updating of user details.
    If the request method is POST, it validates the update form and updates the user details.
    If the form is valid, it saves the updated details and redirects to the profile page.
    If the form is not valid, it renders the edit profile page with the form.
    If the request method is GET, it renders the edit profile page with the user's current details.
    """
    if request.method == 'POST':
        user_form = UserUpdateForm(request.POST, instance=request.user)
        profile_form = ProfileUpdateForm(
            request.POST, request.FILES, instance=request.user.profile)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, 'Your profile has been updated')
            return redirect('profile')
    else:
        user_form = UserUpdateForm(instance=request.user)
        profile_form = ProfileUpdateForm(instance=request.user.profile)
    return render(request, 'users1/edit_profile.html', {'user_form': user_form, 'profile_form': profile_form})
from django.db.models.signals import post_save
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):
    """
    Creates a profile for the user when a user is created.
    """
    if created:
        Profile.objects.create(user=instance)
 
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    """
    Saves the profile when the user is saved.
    """
    instance.profile.save()
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
 
class Profile(models.Model):
    """
    Model for the user profile.
    """
    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'
 
    def save(self, *args, **kwargs):
        """
        Overrides the save method to resize the profile image before saving.
        """
        super().save(*args, **kwargs)
 
        img = Image.open(self.image.path)
 
        if img.height > 300 or img.width > 300:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.image.path)
from django.urls import path
from . import views
 
urlpatterns = [
    path('profile/', views.profile, name='profile'),
    path('edit_profile/', views.edit_profile, name='edit_profile'),
]
from django.apps import AppConfig
 
class UsersConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'APPNAME'
 
    def ready(self):
        '''
        Importing signals to make sure that the signals are imported when the app is ready.
        '''
        import APPNAME.signals
from django.db.models.signals import post_save
from django.contrib.auth.models import User # sender (User) is the model that sends the signal
from django.dispatch import receiver # receiver is the function that gets the signal and performs some task
from .models import Profile
 
@receiver(post_save, sender=User) # when a user is saved, send this signal (post_save) and the receiver (create_profile) will receive it
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance) # instance is the user that was created
 
@receiver(post_save, sender=User) # when a user is saved, send this signal (post_save) and the receiver (save_profile) will receive it
def save_profile(sender, instance, **kwargs):
    instance.profile.save()