我删除了之前的问题,因为它措辞严厉,而且我的非工作示例只是令人困惑。
我有一系列模型,例如Vehicle
,Computer
,Chair
等等。我的目标是能够将任意数量的图像附加到每个图像上。这就是我的问题:实现这一目标的最佳设计模式是什么?
到目前为止,我所尝试的是创建一个抽象模型AttachedImage
。然后,我继承此模型,并创建更具体的模型,例如VehicleImage
,ComputerImage
或ChairImage
。但这并不是追求这一目标的正确方法。
答案 0 :(得分:2)
正如我在删除问题的评论中提到的,正确的方法是使用generic relations。
使您的AttachedImage模型具体化,但添加content_type
和object_id
字段以及content_object
GenericForeignKey。该content_object字段现在可以指向任何模型的实例。
为了使反向关系更容易,您可以将GenericRelation访问者添加到Vehicle,Computer和Chair模型中。
答案 1 :(得分:0)
如果您不想使用GenericForeignKey,您可以实现自己的多态模型,具有多个表继承。以下是相同的伪模型:
class Attachable(models.Model):
pass
class Image(models.Model):
attachable = models.ForeignKey(Attachable, related_name='images')
class Video(models.Model):
attachable = models.ForeignKey(Attachable, related_name='videos')
class Vehicle(Attachable):
vehicle attrs...
class Computer(Attachable):
computer attrs...
class Chair(Attachable):
chair attrs...
对于以后的优化,Attachable
也可以有一个描述其子类型的属性。
答案 2 :(得分:0)
感谢Daniel Roseman,我发现了generic relationships。您可以找到关于它们的精彩概述和教程here。基本上有两种方法可以做到这一点。
第一个使用通用关系,如我链接的教程中所述。这个系统非常通用且功能强大,但在我的情况下,这会增加额外的复杂性,坦白说我不需要。
如果你是像我一样的Django新手,你可以考虑一个更简单,但更少'系统'的模式,我在链接的教程中也详细说明:只需为每一个添加一个ForeignKey
字段您希望主模型与之相关的对象。按照我在问题中使用的示例:
class AttachedImage(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_path) # TO FIX: añadir la ruta
is_default = models.BooleanField(default=False)
为此,您只需添加所需关系的字段,例如:
parent_vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE, null=True)
parent_computer = models.ForeignKey(Computer, on_delete=models.CASCADE, null=True)
parent_chair = models.ForeignKey(Chair, on_delete=models.CASCADE, null=True)
只需像往常一样使用它们。缺点是你不需要的所有额外字段结束,但是它们是NULLable,它们不会占用太多空间。另一个缺点是,使用大量模型执行此操作可能有点过分,在这种情况下,您应该使用第一个解决方案。