【问题标题】:No value of the instance's field when creating another object with Signal使用 Signal 创建另一个对象时,实例的字段没有值
【发布时间】:2016-06-24 16:02:30
【问题描述】:

我有一个标签模型、一个新闻模型和一个活动模型。一个新闻对象可以有很多标签。一个活动对象也可以有很多标签。

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()

news 对象的创建没有任何问题,它具有所有填充的值(包括标签)。活动对象也被创建,没有任何问题。但是,新闻对象的标签没有被初始化到活动对象中。甚至activity.verb 的值也是None,它应该给我一个新闻对象标签之一的标签名称。

即使这样也行不通

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

我在这里缺少什么?您的帮助将不胜感激。谢谢。

【问题讨论】:

  • 我猜here 你会找到问题的解释。
  • @SergeyZherevchuk 就是这样。我相应地改变了信号。非常感谢。

标签: django django-models django-signals


【解决方案1】:

因此,通过 Sergey 非常有帮助的评论,我能够将 News 对象的标签添加到 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()

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

【讨论】:

    猜你喜欢
    • 2013-09-13
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    相关资源
    最近更新 更多