使用Signal

时间:2016-06-24 16:02:31

标签: django django-models django-signals

我有一个标签模型,一个新闻模型和一个活动模型。新闻对象可以有许多标签。活动对象也可以包含许多标记。

class Tag(models.Model):
    name = models.CharField(max_length=20, unique=True)

class News(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=150)
    tags = models.ManyToManyField(Tag)
    activity = GenericRelation(Activity)

class Activity(models.Model):
    actor_type = models.ForeignKey(ContentType, related_name='actor_type_activities')
    actor_id = models.PositiveIntegerField()
    actor = GenericForeignKey('actor_type', 'actor_id')
    verb = models.CharField(max_length=10)
    target_type = models.ForeignKey(ContentType, related_name='target_type_activities')
    target_id = models.PositiveIntegerField()
    target = GenericForeignKey('target_type', 'target_id')
    tags = models.ManyToManyField(Tag)

现在,只要使用django Signals创建新的新闻对象,我就会创建一个新的活动对象。

@receiver(post_save, sender=News)
def create_activity(sender, **kwargs):
    if kwargs.get('created', False):
        actor_type = ContentType.objects.get_for_model(kwargs.get('instance').user)
        actor_id = kwargs.get('instance').user.id
        target_type = ContentType.objects.get_for_model(kwargs.get('instance'))
        target_id = kwargs.get('instance').id
        if target_type.name == 'news':
            verb = 'published an article'
        else:
            verb = '-verb-'
        activity, created = Activity.objects.get_or_create(
            actor_type=actor_type,
            actor_id=actor_id,
            verb=verb,
            target_type=target_type,
            target_id=target_id
        )
        tags = activity.target.tags.all()
        activity.tags.add(*tags)
        activity.verb = "%s" % (tags.first())
        activity.save()

新闻对象的创建没有任何问题,它具有所有填充的值(包括标签)。还会创建活动对象而不会出现任何问题。但是,新闻对象的标签未初始化为活动对象。即使activity.verb的值也是None,它应该给我一个标签名称作为新闻对象标签之一。

即使这不起作用

tags = kwargs.get('instance').tags.all()

我在这里缺少什么?你的帮助将非常感激。谢谢。

1 个答案:

答案 0 :(得分:0)

因此,谢尔盖非常有帮助的评论,我能够将新闻对象的标签提供给Activity对象。

我将post_save信号更改为m2m_changed信号。并且还将if kwargs.get('created', False')更改为if action=='post_add'

@receiver(m2m_changed, sender=News.tags.through)
def add_tags_to_activity(sender, action, instance, **kwargs):
    if action == 'post_add':
        actor_type = ContentType.objects.get_for_model(instance.user)
        actor_id = instance.user.id
        target_type = ContentType.objects.get_for_model(instance)
        target_id = instance.id
        pub_date = instance.pub_date
        if target_type.name == 'news':
            verb = 'published an article'
        else:
            verb = '-verb-'
        activity, created = Activity.objects.get_or_create(
            actor_type=actor_type,
            actor_id=actor_id,
            verb=verb,
            target_type=target_type,
            target_id=target_id,
            pub_date=pub_date
        )
        activity.tags.add(*tags)
        activity.save()

也许这会对像我这样的其他用户有所帮助。