简体   繁体   中英

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

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. The Main folder can also have files which do no belong to the subdirectories.

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

You can simulate theese structures with a self-referenced relation in the CaseFolder model, checkout:

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 .

To provide an alternative. You can use django-mptt .

pip install django-mptt

In your settings.py add mptt into the 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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