如何将一个对象的字段复制到另一个对象的字段
How to copy an object's field to another object's field
我有一个 activity 模型,它会在创建新闻对象时创建一个 activity 对象。 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)
现在使用信号,我尝试以这种方式获取新闻对象的标签,
@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' is an invalid keyword argument for this function
如何将新闻对象的标签复制到 Activity 对象的标签列表?
我认为将 kwargs.get('instance') 存储在变量中然后使用它会更简洁。这也将消除您的错误。然后必须在创建 activity 对象后分配标签。
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()
你应该注意你得到的回溯。即使您没有在此处发布它,也可以清楚地看到错误是在您创建 Activity 时出现的,而不是在您从新闻中读取标签时出现的。那是因为在实例化模型时无法为多对多字段传入数据 - 因为需要先保存对象,然后才能为其分配 M2M 关系。
您应该从 get_or_create
调用中取出 tags
行,然后再分配它们。
我有一个 activity 模型,它会在创建新闻对象时创建一个 activity 对象。 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)
现在使用信号,我尝试以这种方式获取新闻对象的标签,
@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' is an invalid keyword argument for this function
如何将新闻对象的标签复制到 Activity 对象的标签列表?
我认为将 kwargs.get('instance') 存储在变量中然后使用它会更简洁。这也将消除您的错误。然后必须在创建 activity 对象后分配标签。
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()
你应该注意你得到的回溯。即使您没有在此处发布它,也可以清楚地看到错误是在您创建 Activity 时出现的,而不是在您从新闻中读取标签时出现的。那是因为在实例化模型时无法为多对多字段传入数据 - 因为需要先保存对象,然后才能为其分配 M2M 关系。
您应该从 get_or_create
调用中取出 tags
行,然后再分配它们。