如何将对象的字段复制到另一个对象的字段

时间:2016-06-22 19:12:57

标签: django django-models django-contenttypes

我有一个活动模型,每当创建一个News对象时,它就会创建一个活动对象。 News对象有自己的标签。

class Tag(models.Model):
    slug = models.SlugField()

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()
    ...
    ...
    target_type = models.ForeignKey(ContentType, related_name='target_type_activities')
    target_id = models.PositiveIntegerField()
    target = GenericForeignKey('target_type', 'target_id')
    tags = models.ManyToManyField(Tag)

现在使用信号,我尝试以这种方式获取News对象的标签,

@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
        ...
        ...
        # this didn't work
        tags = kwargs.get('instance').tags.all()
        # even this didn't work
        tags = target_type.get_object_for_this_type(id=target_id).tags.all()

        activity = Activity.objects.get_or_create(
            actor_type=actor_type,
            actor_id=actor_id,
            verb=verb,
            target_type=target_type,
            target_id=target_id,
            tags=tags,
            pub_date=pub_date
        )

但是我收到了一个错误:

  

'tags'是此函数的无效关键字参数

如何将News对象的标签复制到Activity对象的标签列表?

2 个答案:

答案 0 :(得分:1)

我认为将kwargs.get(' instance')存储在变量中然后使用它会更加清晰。这也将摆脱你的错误。然后在创建活动对象后必须分配标记。

if kwargs.get('created', False):
    news_obj = kwargs.get('instance')
    if not news_obj:
        return
    actor_type = ContentType.objects.get_for_model(news_obj.user)
    actor_id = news_obj.user.id
    target_type = ContentType.objects.get_for_model(news_obj)
    target_id = news_obj.id
    ...
    ...
    tags = news_obj.tags.all()

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

答案 1 :(得分:0)

你应该注意你得到的追溯。即使你没有在这里发布它,但是很明显,当你创建Activity时错误就会出现,而不是当你从News中读取标签时。这是因为当您实例化模型时,您无法传递多对多字段的数据 - 因为在您可以为其分配M2M关系之前需要保存对象。

您应该从tags电话中取出get_or_create行,然后再分配。