简体   繁体   English

具有Django模型,该模型可以属于其他两个模型之一(外键关系)

[英]Having a django model which can belong to either of two other models (foreign key relation)

I'm trying to emulate a file browser application using django. 我正在尝试使用django模拟文件浏览器应用程序。 My basic models are where a user has a project and the project has files and other subdirectories which also can have files. 我的基本模型是用户有​​一个项目,该项目有文件和其他子目录(其中也可以有文件)。

this is my models.py file 这是我的models.py文件

class CaseFolder(models.Model):
    name = models.CharField(max_length = 255)

class SubFolders(models.Model):
    name = models.CharField(max_length = 255)
    case = models.ForeignKey(CaseFolder)

class Documents(models.Model):
    file = models.FileField(upload_to=set_upload_path)
    belongs_to = models.ForeignKey(SubFolders)

As of now , I'm creating a "MAIN" folder which basically is the root folder which has the other subdirectories. 到目前为止,我正在创建一个“ MAIN”文件夹,该文件夹基本上是具有其他子目录的根文件夹。 The Main folder can also have files which do no belong to the subdirectories. Main文件夹中还可以包含不属于子目录的文件。

It would be preferable if I can eliminate the need for a 'main' folder by having the Documents model refer to Root folder if they dont want to belong to a subdirectory. 如果我可以通过将Documents模型引用到Root文件夹(如果它们不想属于一个子目录)来消除对“ main”文件夹的需要,那将是更好的选择。 THe only way i see around this is the below. 以下是我所见的唯一方法。 But would like to know if theres a better way 但想知道是否有更好的方法

class Documents(models.Model):
    file = models.FileField(upload_to=set_upload_path)
    belongs_to = models.ForeignKey(SubFolders,Null = True)
    belongs_to_root = models.BooleanField(deafult=False)

Forget about the SubFolders model. 忘记SubFolders模型。

You can simulate theese structures with a self-referenced relation in the CaseFolder model, checkout: 您可以在CaseFolder模型中通过自引用关系来模拟这些结构,并结帐:

class CaseFolder(models.Model):
    name = models.CharField()
    parent = models.ForeignKey('self', blank=True, related_name='subfolders')

class Document(models.Model):
    file = models.FileField(upload_to=set_upload_path)
    belongs_to = models.ForeignKey(CaseFolder)

To know if a Document belongs to the root, just use document.belongs_to.parent is None . 要知道Document属于根,只需使用document.belongs_to.parent is None

To provide an alternative. 提供替代方案。 You can use django-mptt . 您可以使用django-mptt

pip install django-mptt

In your settings.py add mptt into the REQUIRED_APPS . 在您的settings.py中,将mptt添加到REQUIRED_APPS

What this allows you to do is the following in your models: 这允许您在模型中执行以下操作:

from mptt.models import MPTTModel, TreeForeignKey

class CaseFolder(MPTTModel):
    name = models.CharField()
    parent = models.TreeForeignKey('self', blank=True, related_name='subfolder', db_index=True)

class MPTTMeta:
    order_insertion_by = ['name']

What this does on the database side is index the table to allow referencing between parent and child. 在数据库方面,这是对表进行索引,以允许在父子之间进行引用。 This will (in theory) make your queries to the database easier and speed up your application as it grows. 从理论上讲,这将使您对数据库的查询更加轻松,并随着应用程序的增长而加快其速度。 It also simplifies how the data is queried. 它还简化了如何查询数据。

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

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