Django:使用GenericRelation字段复制模型的实例

时间:2011-02-10 06:44:05

标签: django django-models

我有一个包含GenericRelation

的简单类
class Item(models.Model):
    name  = models.CharField ( max_length=50, null=True, blank=True )
    image = generic.GenericRelation(Image)

class Image(models.Model):
    file  = models.FileField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

要制作项目的副本,我可以设置Item.id = None并保存:

item = Item.objects.get(id=3)
item.id = None
item.save()
# item is now a copy of the original item

不幸的是,这不会将图像字段复制到新实例。

我尝试手动复制它:

item = Item.objects.get(id=3)
images = item.image.all()
item.id = None
item.save()
item.image = images

然而,这会从原始实例中删除图像,有效地将它们移动到第二个实例而不是复制。

将图像复制到新实例的好方法是什么?

2 个答案:

答案 0 :(得分:1)

您的问题是,通过您当前定义模型的方式,每个图像只能引用一个“项目”(或任何其他模型)。

这会实现你所需要的吗?:

class Image(models.Model):
    file  = models.FileField()

class Item(models.Model):
    name  = models.CharField ( max_length=50, null=True, blank=True )
    images = models.ManyToManyField(Image, related_name="images_set")

在访问项目图像之前,您可能会有类似以下代码:

images_of_item = my_item.image.all()

你现在会有类似的东西:

images_of_item = my_item.images_set.all() 

或者在您使用Generic Relations之前,因为您需要跟踪不同模型的不同对象的“图像”,但每个项目不需要多个图像,这可能会更好:

class Image(models.Model):
    file  = models.FileField()

class Item(models.Model):
    name  = models.CharField ( max_length=50, null=True, blank=True )
    image = models.ForeignKey(Image)

和以前一样代替类似的代码:

image_of_item = my_item.image.all()

你的代码类似于......嗯:

the_items.image = my_item.images.all()

如果你看一下django为你问题中包含的模型生成的表结构,可能你有一个名为appname_Image的表,它有一个FK列,它连接一个Image和一个基于模型的模型实例。两个字段content_type_idobject_id,知道每个图像都由一行表示,您可以看到每个“图片”只能连接到一个“项目”(或任何其他型号)。

如果您要使用我的第一个建议,Django会生成一个joiner表,允许您将多个图像与多个项目相关联。 - 如果您尝试的是使用通用外键实现的是使多种类型的模型与图像相关联,并且您希望每个模型有多个图像,这是可行的方法,将ManyToMany字段添加到需要与多个图像关联的每个模型

如果您要使用我的第二个示例,Django将负责维护Item(和其他模型,如果您添加类似的ForeignKey)及其表的Item-Image关系。您的appname_Item表可能有一个名为image_id的FK列。 - 如果您尝试使用通用外键实现的目的是使多种类型的模型与图像相关联,但是您没有每个模型需要多个图像,这是要采用的方法,将ForeignKey字段添加到需要与单个图像关联的每个模型

答案 1 :(得分:1)

回答我自己的问题:我最终手动制作图像副本并设置其object_id:

item = Item.objects.get(id=3)
image = item.image.all()[0]

image.id = None
image.object_id = new_item.id
image.save()