【发布时间】:2015-03-04 09:55:36
【问题描述】:
我是 Django 新手,无法理解如何使用 Django 信号。谁能用简单的例子解释一下“Django 信号”?
提前致谢。
【问题讨论】:
-
你能说得更具体点吗?该手册已经有一些示例:docs.djangoproject.com/en/1.7/topics/signals
标签: python django django-signals
我是 Django 新手,无法理解如何使用 Django 信号。谁能用简单的例子解释一下“Django 信号”?
提前致谢。
【问题讨论】:
标签: python django django-signals
你可以通过非常小的研究在互联网上找到关于 django 信号的非常好的内容。
在这里,我将向您简要介绍 Django 信号。
什么是 Django 信号?
信号允许某些发送者通知一组接收者某些动作已经发生
行动:
模型的 save() 方法被调用。
django.db.models.signals.pre_save | post_save
模型的 delete() 方法被调用。
django.db.models.signals.pre_delete | post_delete
模型上的 ManyToManyField 已更改。
django.db.models.signals.m2m_changed
Django 启动或完成一个 HTTP 请求。
django.core.signals.request_started |请求完成
所有信号都是 django.dispatch.Signal 实例。
models.py
from django.db import models
from django.db.models import signals
def create_customer(sender, instance, created, **kwargs):
print "Save is called"
class Customer(models.Model):
name = models.CharField(max_length=16)
description = models.CharField(max_length=32)
signals.post_save.connect(receiver=create_customer, sender=Customer)
壳牌
In [1]: obj = Customer(name='foo', description='foo in detail')
In [2]: obj.save()
Save is called
【讨论】:
signals.post_save.connect(receiver=create_customer, sender=Customer)是在Customer模型的定义之后调用的?另外,为什么那行不缩进?即使没有调用类定义,那行也不会执行吗?即如果 models.py 被导入到任何地方,但实际上没有调用来自 models.py 的对象(类定义、函数等)。
除了explanation given by Prashant,你还可以使用django.dispatch模块中的receiver装饰器。
例如
from django.db import models
from django.db.models import signals
from django.dispatch import receiver
class Customer(models.Model):
name = models.CharField(max_length=16)
description = models.CharField(max_length=32)
@receiver(signals.pre_save, sender=Customer)
def create_customer(sender, instance, created, **kwargs):
print "customer created"
有关详细信息,请参阅此link。
【讨论】:
signals.post_save 使用,在你的答案中从 signals.pre_save 使用,它们之间有什么区别?
post_save 用法很清楚,但pre_save 的用法是什么?
在 signals.post_save.connect(receiver=create_customer, sender=Customer)... sender 将始终是我们定义的模型...或者我们也可以在 sender 中使用 User。
【讨论】:
信号用于对模型实例的修改执行任何操作。信号是帮助我们将事件与动作联系起来的实用程序。我们可以开发一个在信号调用时运行的函数。换句话说,信号用于对数据库中特定条目的修改/创建执行一些操作。例如,一旦在数据库中创建了一个新的用户实例,就会想要创建一个配置文件实例
有 3 种信号类型。
其中一个示例,如果我们想在使用 post_save 信号创建用户后立即创建用户的个人资料。
对于代码示例,我找到了 Geeks for Geeks,它的解释方式非常简单,易于理解。 https://www.geeksforgeeks.org/how-to-create-and-use-signals-in-django/
【讨论】:
您可以将信号添加到您的 models.py 文件中
如果您使用 SlugField,这里是添加自动 slug 的示例:
这是你需要导入的东西
from django.utils.text import slugify
from django.dispatch import receiver
from django.db.models.signals import post_save, pre_save
将@receiver 添加到类的底部,包括def
如果在receiver下面加上
def __str__(self):会报错
class Store(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=False, blank=True, null=True)
def __str__(self):
return self.name
@receiver(pre_save, sender=Store)
def store_pre_save(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = slugify(instance.name)
或者您可以使用 post_save
class Store(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=False, blank=True, null=True)
def __str__(self):
return self.name
@receiver(post_save, sender=Store)
def store_post_save(sender, instance, created, *args, **kwargs):
if not instance.slug:
instance.slug = slugify(instance.name)
instance.save()
我从tutorial找到了这个例子
【讨论】: