带角色装饰器的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
相关产品推荐
相关产品推荐

