django-mptt - How to set different models in the same tree

django, django-mptt

Solution

You can combine the MPTTModel with a generic relation from the contenttypes framework. You can enable it by adding 'django.contrib.contenttypes' to your INSTALLED_APPS setting.

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey

class TreeItem(MPTTModel):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children')

class Folder(models.Model):
    name = models.CharField(max_length=50)
    type = models.CharField(max_length=50)

class File(models.Model):
    filename = models.CharField(max_length=255)
    encoding = models.CharField(max_length=20)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

The mptt documentacion explains how to access the tree in your templates.

Problem

I would like to have a tree that would mimic a file system with folders and files. Folders and files would be defined by different models with different fields attributes. models: ``` from mptt.models import MPTTModel, TreeForeignKey class Folder(MPTTModel): parent = TreeForeignKey('self', null=True, blank=True, related_name='children') name = models.CharField(max_length=50) type = models.CharField(max_length=50) class File(MPTTModel): parent= TreeForeignKey(Document) filename = models.CharField(max_length=255) encoding = models.CharField(max_length=20) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) ``` Creating some folders and files: ``` from shapefile.models import Folder, File root = Folder.objects.create(name="Root") download = Folder.objects.create(name="Download", parent=root) upload = Folder.objects.create(name="Upload", parent=root) File.objects.create(filename="Test", encoding="UTF-8", parent=download) ``` Shoul have: ``` > Root > --Download > ----Test > --Upload ``` How can I retrieve this tree in view and template? Edit: Files are not inserted as folder's nodes: ``` file = File.objects.get(filename="Test") file.get_ancestors() >>> [] ```

Original source