潘飞

潘飞的博客

他的个人主页  他的博客

Using Django's built-in signal

潘飞  2009年09月11日 星期五 14:42 | 1985次浏览 | 0条评论

Using Django's built-in signals

REF:http://www.mercurytide.co.uk/news/article/django-signals/

 

用post_save比较多吧,也就是说在存储了一个Model的实例到数据库后就触发这个信号,很自明。

 

下面引用的代码(去了一些没用的)在django 1.0+中好象已经不对了,不过可以说明问题

 

from django.contrib.auth.models import User
from django.db import models
from django.db.models import signals
from django.dispatch import dispatcher
from myproject.blog.signals import send_entry_created_email


class Entry(models.Model):
      """An individual entry (post) in a blog."""
      headline = models.CharField(maxlength=255)
      slug = models.SlugField(prepopulate_from=
           ['headline'], unique_for_year='published')
      body = models.TextField()
      published = models.DateTimeField()
      author = models.ForeignKey(User)

dispatcher.connect(send_entry_created_email,signal=signals.post_save,

sender=Entry)

 

这是个什么东西?__doc__很清楚:An individual entry (post) in a blog  就是在blog中发表东西吗!

要达到这样一个目的:每发一个Entry这样的东西,就往一些人的mailbox里发邮件,通知那些人说:“某某某发表了新东西了!”

有signal就好办了:

dispatcher.connect(send_entry_created_email,signal=signals.post_save,

sender=Entry) #这个在1.+中有好象不这样写了,自己see文档;

以上这个东西,就是办这个事情的:看参数要从后往前看,Entry是触发信号的那个Model,可是总不能乱发吧,所以看第二个参数,是在post_save这个信号触发的时候才发;发了信号做什么,当然是让send_entry_created_email来执行了。

这其中send_entry_created_email是必须的,也就是说必须有一个接东西的,还有,sender=Entry这个东西可以省略,可是那样的话,其他的,比如User的post_save信号,也将触发send_entry_created_email,这样就不合适了,不过或许也有合适的情况,暂且没想到。

总的来说就是,当Entry的一个实例save后,发post_save信号的时候,要执行send_entry_created_email这个函数,或者叫callable。

做了上面的工作之后,你每发一个文章后,save的时候,这个send_entry_created_email就会执行。那很显然这个send_entry_created_email东西就很有趣了,它都干了什么事情呢?:

from django.core.mail import send_mass_mail
from django.template import Context, loader
from myproject.blog.models import Post


def send_entry_created_email(sender, instance, signal, *args, **kwargs):
     """
     Sends an email out to a number of people informing
     them of a new blog entry.
     """
     def get_recipient_list():
         recipient_list = [] # Left for you to implement.
         return recipient_list

     try:
         Post.objects.get(id=instance._get_pk_val())
     except (Post.DoesNotExist, AssertionError):
         # that this is a new post.
         t = loader.get_template('blog/new_entry_email.txt')
         c = Context({
         'entry': instance,
         })
         message = t.render(c)

         subject = 'A new blog entry is available'
         from_email = instance.author.email
         recipient_list = get_recipient_list()

         email = (subject, message, from_email, recipient_list)
         send_mass_mail(email)

post_save信号在发出的同时,也往外扔一些参数:

sender:Model,在这里就是Entry了;

instance:就是你存的那个Entry的instance;

created:很有用,这是一个bool值,表明是不是创建的新实例;在这里我们应该只是在新创建的时候才发送邮件,而这个作者好象没这样写,而是写的异常,看看这个东东在Post里面有没有,没有的话当然就是创建(created=True)了(是不是忘了save这个post了?),真是条条大路通北京啊!当然,既然提供,那就用吧,反正是免费的。

然后你发一个文章的时候就会调用send_entry_created_email这个东西了,每新发一个文章就发电子邮件。END

 

 

评论

我的评论:

发表评论

请 登录 后发表评论。还没有在Zeuux哲思注册吗?现在 注册 !

暂时没有评论

Zeuux © 2024

京ICP备05028076号