为何新增Robot表条目时Django信号未触发?求排查
问题描述
我创建了一个信号,用来检测Robot表的新增条目,将其model和version数据与Order表比对后发送邮件,但完全没效果。我试过把信号文件放到不同文件夹,还在函数里加了print语句,但连输出都没有。
相关代码
信号处理代码
@receiver(post_save, sender=Robot) def robot_created(sender, instance, **kwargs): orders = Order.objects.all() for order in orders: robot_exists = Robot.objects.filter(model=order.robot_model, version=order.robot_version).exists() if robot_exists: subject = 'text' message = 'text' from_email = 'text@gmail.com' recipient_list = ['text22@gmail.com'] send_mail(subject, message, from_email, recipient_list)
Order模型(order.models.py)
class Order(models.Model): customer = models.ForeignKey(Customer,on_delete=models.CASCADE) robot_model = models.CharField(max_length=2, blank=True,null=True) robot_version = models.CharField(max_length=2, blank=True,null=True)
Robot模型(robots.models.py)
class Robot(models.Model): serial = models.CharField(max_length=5, blank=False, null=False) model = models.CharField(max_length=2, blank=False, null=False) version = models.CharField(max_length=2, blank=False, null=False) created = models.DateTimeField(auto_now_add=True)
可能的问题及解决方法
信号未完成注册:Django不会自动加载信号文件,必须在应用启动时手动导入。解决方法:在
robots/apps.py的ready()方法中导入信号:from django.apps import AppConfig class RobotsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'robots' def ready(self): import robots.signals # 替换成你的信号文件实际路径同时确保项目
settings.py的INSTALLED_APPS中注册的是这个配置类,而非直接写'robots':INSTALLED_APPS = [ # ... 'robots.apps.RobotsConfig', # ... ]信号逻辑完全错误:当前逻辑是遍历所有订单,检查是否存在对应机器人——但这是在新增机器人之后做的,且匹配方向完全搞反。正确逻辑应该是:用刚新增的机器人(
instance)的model和version,去查找有没有对应的订单,而非反过来。未过滤新增动作:
post_save信号在机器人新增和更新时都会触发,你没有判断created参数,导致非新增场景也会执行代码,还可能重复发送邮件。邮件配置未正确设置:即使信号触发,如果Django的邮件配置(如
EMAIL_BACKEND、EMAIL_HOST、EMAIL_PORT等)未在settings.py中正确配置,邮件也无法发送,且可能无报错提示。
修正后的信号代码
from django.db.models.signals import post_save from django.dispatch import receiver from django.core.mail import send_mail from .models import Robot from orders.models import Order @receiver(post_save, sender=Robot) def robot_created(sender, instance, created, **kwargs): # 只处理新增的机器人 if not created: return # 查找匹配当前机器人的订单 matching_orders = Order.objects.filter( robot_model=instance.model, robot_version=instance.version ) if matching_orders.exists(): subject = '匹配订单的机器人已创建' message = f"型号{instance.model}、版本{instance.version}的机器人已新增,对应订单已找到" from_email = 'text@gmail.com' recipient_list = ['text22@gmail.com'] send_mail(subject, message, from_email, recipient_list)
内容的提问来源于stack exchange,提问作者Artem Kusch
相关产品推荐
相关产品推荐

