潘飞 2009年09月11日 星期五 14:42 | 2065次浏览 | 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 © 2024
京ICP备05028076号
暂时没有评论