Home > Mobile >  How to use Django signals when has role based decorators?
How to use Django signals when has role based decorators?

Time:12-05

Update, I have created a signal file like this, so for example if an employer has created a shift, the admin will get an email notification like this:

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Shift

from django.core.mail import send_mail


@receiver(post_save, sender=Shift)
def send_mail_to_user(sender, instance, created, **kwargs):
    if created:
        send_mail(
                'A new shift has been created by employer xxx',
                'Here is the message.',
                '[email protected]',
                ['[email protected]'],
                fail_silently=False,
            )

Original post:

Hi, I 'm trying to add signals when an employer or admin/staff has created a shift. Currently I have a view like this, I 'm wondering how should I modify it so I can have a post-save signal?

@login_required
@admin_staff_employer_required

def createShift(request):
    user=request.user
    employer=Employer.objects.all()
    
    form = CreateShiftForm()
    if request.method == 'POST':
        form = CreateShiftForm(request.POST)

        if form.is_valid():

            form.save()
            messages.success(request, "The shift has been created")

            return redirect('/shifts')
        else:
            messages.error(request,"Please correct your input field and try again")

    context = {'form':form}

    return render(request, 'create_shift.html', context)

Thanks for your help!

CodePudding user response:

Try this(in this case I suppose your app name is 'almo' and model name is 'Shift').

signals.py

from .models import Shift
from django.dispatch import receiver
from django.db.models.signals import post_save

@receiver(post_save, sender=Shift)
def shift_created_callback(sender, **kwargs):
    print('shift created!')
    # do something

# arguments can be added by your taste
# def shift_created_callback(sender, instance, **kwargs):
# def shift_created_callback(sender, instance, created, **kwargs):

apps.py

from django.apps import AppConfig

class AlmoConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'almo'

    def ready(self):
        import almo.signals

You can see 'shift created' in console when you create shift

CodePudding user response:

You have to create a new function that will be the receiver of the post-save signal. It is explained here in the docs: https://docs.djangoproject.com/en/4.1/topics/signals/#connecting-to-signals-sent-by-specific-senders

Basically, you would need to set the sender to your model class, and on every post_save signal the handler function would get triggered. If you need a specific signal you can create your custom ones: https://thetldr.tech/how-to-add-custom-signals-dispatch-in-django/ , but for your use case you can trigger the function on every save of the shift model.

from django.db.models.signals import post_save
from django.dispatch import receiver
#here you have to import your Shift model


@receiver(post_save, sender=Shift)
def my_handler(sender, **kwargs):
    print('Shift created')

Also import the signals file in your apps.py file like so:

from django.apps import AppConfig


class ApplicationConfig(AppConfig):
    name = "<your app name>"

    def ready(self):
        from <app_name> import <signal_recievers_file_name>

This should print "Shift created" to your console once you create a new shift.

  • Related