杭州电子商务研究院

Django Signals 简介

2020-10-28 08:00飞浪

介绍

将数据保存到数据库时,存在一些特殊用例,即应用程序的业务需求可能需要在保存数据之前或之后进行一些处理。这意味着应该有一种方法可以知道数据何时即将保存或刚刚通过 Django 模型方法save()保存到数据库中。

一种可能的方法是重写每个模型上的save()方法。

一种更简洁、更高效的方法是使用Django 信号。这些组件基于发送者和接收者的概念工作。发送组件通常是模型,而接收组件通常是处理函数,一旦收到数据即将保存或刚刚保存的通知,它就会对数据进行处理。

本指南将探讨如何在 Django 中使用信号作为在数据进入数据库的过程中或刚保存到数据库之后对数据进行预处理和后处理的方法。本指南假设您至少具有 Django 的初级知识,并且对 Django MVC(尤其是模型组件)有一般了解。Django 的入门指南可在此处找到,Django 模型的复习指南可在此处找到。

用例场景

考虑这样一个用例:您有一个包含订单和库存模型的电子商务 Django 应用。业务逻辑是这样的:在保存订单之前,应检查库存以确保商品有货。
此外,在保存订单后,应该有一个逻辑来发送已收到订单的通知。以下是示例模型的代码块。

      from django.db import models
from django.contrib.auth.models import User
class Inventory(models.Model):
    item = models.CharField(max_length=20)
    item_code = models.IntegerField()
    item_condition = models.CharField(max_length=50)
    quantity = models.IntegerField()
    def __str__(self):
        return self.item

class Order(models.Model):
    ord_number = models.CharField(max_length=20)
    inventory_item = models.ForeignKey(Inventory)
    ordered_by = models.ForeignKey(User)
    quantity = models.IntegerField()
    def __str__(self):
        return self.ord_number
    

预存信号

在将数据保存到数据库之前必须执行逻辑的情况下,会使用预保存信号。在您的例子中,这涉及通过检查商品是否存在于库存中来确定订单是否有效。下面的代码块定义了一个函数来实现此目标。该函数可以存在于models.py中。

      from django.db.models.signals import pre_save
def validate_order(sender, instance, **kwargs):
    if instance.quantity < instance.inventory_item.quantity: # order can be fulfilled
        instance.save()
    else:
        # write logic to reject save and give message why

pre_save.connect(validate_order, sender=Order)
    

在上面的代码块中,您已经在validate_order()函数中定义了您的业务逻辑并使用了pre_save函数,并且您已经将接收方函数连接到发送方,即Order模型。

保存后信号

在这里,您可以通知用户订单已成功接收。post_save逻辑只是一个普通函数,即接收函数,但它与发送器(即订单模型)相连。下面的代码块演示了作为后保存的示例接收函数。

      from django.db.models.signals import post_save
from myapp.utils import send_notification

def notify_user(sender, instance, **kwargs):
   send_notification(instance.ordered_by)

post_save.connect(notify_user, sender=Order)
    

这样,一旦订单成功下达,客户将通过电子邮件或短信收到通知,具体取决于业务用例的需求。

结论

了解 Django 信号后,您现在可以构建强大的 Web 应用,这些应用可以在保存前和保存后预处理数据。这种灵活性还允许您构建自定义工作流,以更好地满足特定用例的需求。

要以本指南为基础,请更多地研究信号和接收器,包括它们的工作原理以及是否可以覆盖它们。覆盖使程序员能够自定义预构建函数。您可能还对保存前或保存后信号如何区分新记录保存和现有记录的更新保存感兴趣。

曝光25772浏览1395