使用 Signal 创建另一个对象时实例字段没有值
No value of the instance's field when creating another object with Signal
我有一个标签模型、一个新闻模型和一个 Activity 模型。一个新闻对象可以有很多标签。 activity 对象也可以有很多标签。
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 创建新的新闻对象时,我都会创建一个新的 activity 对象。
@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 对象的创建也没有任何问题。但是,新闻对象的标签并未初始化到 activity 对象中。甚至 activity.verb
的值也是 None
,它应该给我新闻对象标签之一的标签名称。
连这个都不行
tags = kwargs.get('instance').tags.all()
我在这里错过了什么?非常感谢您的帮助。谢谢。
因此,在 Sergey 非常有用的评论下,我能够将新闻对象的标签获取到 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()
也许这对像我这样的其他用户有帮助。
我有一个标签模型、一个新闻模型和一个 Activity 模型。一个新闻对象可以有很多标签。 activity 对象也可以有很多标签。
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 创建新的新闻对象时,我都会创建一个新的 activity 对象。
@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 对象的创建也没有任何问题。但是,新闻对象的标签并未初始化到 activity 对象中。甚至 activity.verb
的值也是 None
,它应该给我新闻对象标签之一的标签名称。
连这个都不行
tags = kwargs.get('instance').tags.all()
我在这里错过了什么?非常感谢您的帮助。谢谢。
因此,在 Sergey 非常有用的评论下,我能够将新闻对象的标签获取到 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()
也许这对像我这样的其他用户有帮助。