简体   繁体   English

创建与任意数量的其他模型相关的模型

[英]Creating a model related to an arbitrary number of other models

I deleted my previous question, since it was terribly worded and my non-working examples were just confusing. 我删除了我之前的问题,因为它的措辞太糟糕了,而且我的非工作示例令人困惑。

I have a series of models, such as Vehicle , Computer , Chair , and whatnot. 我有一系列模型,例如VehicleComputerChair和whatnot。 My goal is to be able to attach an arbitrary number of images to each of them. 我的目标是能够在每个图像上附加任意数量的图像。 That's my question: what's the best design pattern to achieve this? 这是我的问题:实现这一目标的最佳设计模式是什么?

What I've tried so far is to create an abstract model, AttachedImage . 到目前为止,我已经尝试创建一个抽象模型AttachedImage I then inherit from this model, and create more specific models, like VehicleImage , ComputerImage , or ChairImage . 然后,我从该模型继承,并创建更多特定的模型,例如VehicleImageComputerImageChairImage But this doesn't feel like the right way to pursue this. 但这并不适合追求这一目标。

As I mentioned in the comment on the deleted question, the correct way to do this would be to use generic relations . 正如我在已删除问题的评论中提到的那样,正确的方法是使用一般关系

Make your AttachedImage model concrete, but add content_type and object_id fields and the content_object GenericForeignKey. 使您的AttachedImage模型具体,但添加content_typeobject_id字段以及content_object GenericForeignKey。 That content_object field can now point to an instance of any model. 现在,那个content_object字段可以指向任何模型的实例。

To make the reverse relationships easier, you can add GenericRelation accessors to your Vehicle, Computer and Chair models. 为了使反向关系更容易,您可以将GenericRelation访问器添加到Vehicle,Computer和Chair模型中。

If you don't want to use the GenericForeignKey, you can implement your own polymorphic models, with multiple table inheritance. 如果您不想使用GenericForeignKey,则可以实现具有多个表继承的自己的多态模型。 Following are the pseudo-models for the same: 以下是相同的伪模型:

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...   

For later optimizations, Attachable can also have an attribute which describes its subtype. 对于以后的优化, Attachable还可以具有一个描述其子类型的属性。

Thanks to Daniel Roseman's, I found out about generic relationships . 多亏了Daniel Roseman的帮助,我才发现了一般关系 You can find a great overview and tutorial about them here . 您可以在此处找到有关它们的出色概述和教程。 There are basically two ways to achieve this. 基本上有两种方法可以实现此目的。

The first one is using generic relationships as explained in the tutorial I linked. 第一个方法是使用我所链接的教程中介绍的通用关系。 This system is very versatile and powerful, but in my case, this would add an additional layer of complexity that quite frankly I don't need. 该系统非常通用且功能强大,但是就我而言,这将增加一层我很不需要的复杂性。

If you're a newbie with Django like I am, you can consider a much more straightforward, but less 'systematic' pattern, also detailed in that tutorial I linked: simply add a ForeignKey field for each one of the objects you want your main model to be related to. 如果您像我一样是Django的新手,则可以考虑采用一种更为简单但又不太“系统化”的模式,该模式在我链接的教程中也有详细介绍:只需为您想要主对象的每个对象添加一个ForeignKey字段要关联的模型。 Following the example I used in my question: 按照我在问题中使用的示例:

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)

To this, you just add fields for the relationships you will need, such as: 为此,您只需添加所需关系的字段,例如:

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)

And just use them as you regularly would. 然后像平常一样使用它们。 The downside is ending up with all those extra fields you don't really need, but being NULLable, they won't take up much space. 不利的一面是所有您实际上不需要的额外字段结束,但是这些字段可以为空,因此不会占用太多空间。 The other downside is that doing this with a big number of models is probably overkill, in which case you should really use the first solution. 另一个缺点是,使用大量模型执行此操作可能会过大,在这种情况下,您应该真正使用第一个解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM