Django中的Signals和GenericForeignKey的使用

Signals 顾名思义,就是信号的意思。

Django的signals可以用来干什么呢?比如,论坛中别人给你发了一条消息,自动产生一个消息对象。

我们先来自定义一个信号

Message应用中的models.py

from django.db import models
from django.contrib.auth.models import User
from django.dispatch import Signal
notice_signal = Signal(providing_args=['reciver']) #自定义信号
class Message(models.Model):
    sender = models.ForeignKey(User)
    content = models.CharField(max_length=50)
    def newMessage(self,reciver):
        notice_signel.send(sender=self.__class__,reciver=reciver) #发出信号

Notice应用中的models.py

from django.db import models
from django.contrib.auth.modesl import User
from Message.models import notice_signal
class Notice(models.Model):
    reciver = models.ForeignKey(User)
    def sendNotice(sender,reciver,**kwargs):
        Notice.create(reciver=reciver)
notice_signal.connect(sendNotice,sender=Message) #接收信号

这样,只有在创建一个Message对象后,调用newMessage函数,就会自动创建一个Notice对象,实现类似新消息通知的功能。


更复杂的一个例子,我说我要学习,学什么呢,学数据库(一个model),算是学习,学一门语言(另外一个model)也算是学习。我希望每学一样东西,会自动产生一个学习事件model。这样我在查询我所学的知识时,只需要对学习事件进行查询就能够方便获取所有学过的东西的对象。

from django.db import models
from django.contrib.auth.modesl import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
Class StudyEvent(models.Model):
    #以下三个成员必须指定
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    #其它需要字段
    user = models.ForeignKey(User)
    start_time = models.models.DateTimeField(auto_now=True)
    #……
class StudyDatabase(models.Model):
    content = models.CharField(max_length=50)
class StudyLanguage(models.Model):
    content = models.CharField(max_length=50)

因为有时候学数据库和学一门语言要包含一些不同字段,所以需要两个models。


然后,让我们来添加Signal

models.py

#头部添加
from django.db.models.signals import post_save #即对象在创建时会发出的信号
#尾部
def autoCreateStudyEvent(sender,**kwagrs):
    instance = kwargs.get('instance')
    if instance.__class__.__name__ == 'StudyDatabase':
        studyevent = StudyEvent.create(content_object=instance)
  &nbsp;<span></span> elif instance.__class__.__name__ == 'StudyLanguage':
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; studyevent = StudyEvent.create(content_object=instance)
post_save.connect(autoCreateStudyEvent,sender=StudyDatabase)
post_save.connect(autoCreateStudyEvent,sender=StudyLanguage)<span></span>

这样,在创建StudyDatebase和StudyLanguage时会自动创建相应的StudyEvent对象。

现在,例如有一个用户叫user1,获取它所有学过的东西只需要:

import datetime
user1 = User.objects.get(username="user1")
studyevents = user1.studyevent_set.filter(start_time=datetime.datetime(2013,8,11)) #获取在8月11日学到的知识
for studyevent in studyevents:
    print studyevent.content_object

这样的好处在于,以后添加了新的models,在获取所有所学过的知识时,不需要重新添加很多代码。

http://my.oschina.net/u/572994/blog/151871

 

转载于:https://my.oschina.net/shniu/blog/223532

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值