You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带角色装饰器的Django视图中如何配置post_save信号?

问题描述

我想在雇主、管理员或员工创建班次时添加Django信号,当前有带角色装饰器的视图代码,想知道怎么配置来实现post_save信号的功能。

原视图代码:

@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)

我已经写了信号文件,希望雇主创建班次时管理员能收到邮件通知,代码如下:

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.',
                'from@example.com',
                ['to@example.com'],
                fail_silently=False,
            )

实现方案

你的视图代码不需要修改,Django信号是基于模型层触发的,只要完成以下配置,不管通过视图还是其他方式创建Shift实例,都会自动触发post_save信号:

1. 注册信号

Django不会自动识别信号文件,需要在对应app的apps.py中注册:

from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'your_app_name'

    def ready(self):
        # 导入信号文件,确保信号被注册
        import your_app_name.signals

然后在app的__init__.py中添加:

default_app_config = 'your_app_name.apps.YourAppConfig'

2. 完善信号逻辑

你当前的信号内容比较固定,可以优化成动态获取创建者信息、管理员邮箱:

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Shift
from django.core.mail import send_mail
from django.contrib.auth.models import User

@receiver(post_save, sender=Shift)
def send_mail_to_user(sender, instance, created, **kwargs):
    if created:
        # 获取创建班次的用户
        creator = instance.created_by
        # 动态生成邮件主题和内容
        subject = f'A new shift has been created by {creator.get_full_name()} ({creator.role})'
        message = (
            f"Shift details:\n"
            f"Title: {instance.title}\n"
            f"Start time: {instance.start_time}\n"
            f"End time: {instance.end_time}"
        )
        # 获取所有管理员的邮箱
        admin_emails = [user.email for user in User.objects.filter(is_superuser=True)]
        
        send_mail(
            subject,
            message,
            'from@example.com',
            admin_emails,
            fail_silently=False,
        )

3. 关联班次创建者

如果Shift模型还没有记录创建者的字段,需要先添加:

from django.db import models
from django.contrib.auth.models import User

class Shift(models.Model):
    # 原有字段(如标题、时间等)...
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='shifts_created')
    # 其他字段...

同时修改视图中保存表单的逻辑,自动绑定当前用户为创建者:

# 替换原form.save()的逻辑
if form.is_valid():
    shift = form.save(commit=False)
    shift.created_by = request.user
    shift.save()
    messages.success(request, "The shift has been created")
    return redirect('/shifts')

完成以上配置后,不管是雇主、管理员还是员工通过该视图创建班次,都会触发post_save信号,自动给管理员发送包含班次详情的邮件通知。

内容的提问来源于stack exchange,提问作者almo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:15:24