我有一个标签模型,一个新闻模型和一个活动模型。新闻对象可以有许多标签。活动对象也可以包含许多标记。
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()
我在这里缺少什么?你的帮助将非常感激。谢谢。
答案 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()
也许这会对像我这样的其他用户有所帮助。