2012-06-19 4 views
3

Je développe une application hirerchical où les nœuds feuilles peuvent être des instances de modèles différents. Je n'arrive pas à comprendre comment le faire fonctionner avec l'application django-mptt. Est-ce même possible dans cette application? Si oui, qu'est-ce que je fais de mal? et si non, y a-t-il quelque chose là-bas qu'est-ce que j'essaie de faire?Nœuds feuille Django-MPTT de plusieurs types

Ce qui suit est une structure de base des modèles:

class FolderItemBase(MPTTModel): 
    order = models.PositiveIntegerField() 

    class Meta: 
     abstract = True 

    class MPTTMeta: 
     parent_attr = 'folder' 
     order_insertion_by = ['order'] 

class Folder(FolderItemBase): 
    folder = TreeForeignKey('Folder', related_name='folders', blank=True, null=True) 
    ... 

class Image(FolderItemBase): 
    folder = TreeForeignKey('Gallery', related_name='images') # cannot be null since leaf has to be inside of a folder 
    ... 

Quand j'essaie de faire ce que je respecte ne suis en mesure d'obtenir les enfants des dossiers, et aucun des images. Même chose quand j'essaie d'obtenir ancêtres des images

>>> folder1 = Folder.objects.create(title='Folder 1', order=0) 
>>> folder2 = Folder(title='Folder 2', order=0) 
>>> folder2.insert_at(folder1, save=True) 
>>> image = Image(...) 
>>> image.insert_at(folder1, save=True) 
>>> folder1.get_children() 
[<Folder: Folder 2>] 
>>> image.get_ancestores() 
[] 

Et voici comment les choses sont stockées dans la base de données après tout cela:

Folder table 
---------------- 
+----+-------+-----+------+---------+-------+-----------+----------+ 
| ID | order | lft | rght | tree_id | level | folder_id | title | 
+----+-------+-----+------+---------+-------+-----------+----------+ 
| 1 | 0  | 1 | 4 | 1  | 0  |   | Folder 1 | 
+----+-------+-----+------+---------+-------+-----------+----------+ 
| 2 | 0  | 2 | 3 | 1  | 1  | 1   | Folder 2 | 
+----+-------+-----+------+---------+-------+-----------+----------+ 

Images Table 
------------ 
+----+-------+-----+------+---------+-------+-----------+ 
| ID | order | lft | rght | tree_id | level | folder_id | 
+----+-------+-----+------+---------+-------+-----------+ 
| 1 | 1  | 2 | 3 | 1  | 1  | 1   | 
+----+-------+-----+------+---------+-------+-----------+ 

Comme vous pouvez le voir les chiffres qui devraient être le nombre de niveau pour l'image et le bon (au moins il semble être) des nombres gauche et droit mais il ne met pas à jour quoi que ce soit dans la table des dossiers alors quand vous essayez de faire une requête, rien n'est sélectionné.

Les pointeurs sont appréciés. Je vous remercie.

Répondre

6

AFAIK, ce n'est pas possible; django-mptt piggy backs sur QuerySet de Django, qui ne fonctionnera jamais qu'avec un type de choses. Vous pouvez utiliser le framework contenttypes pour associer l'élément "real" à quelque chose comme FolderItem, qui ne serait utilisé que pour la hiérarchie, par ex.

from django.contrib.contenttypes.models import ContentType 
from django.contrib.contenttypes import generic 

class FolderItem(MPTTModel): 
    folder = TreeForeignKey('Folder', related_name='folders', blank=True, null=True 
    order = models.PositiveIntegerField() 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

    class Meta: 
     abstract = True 

    class MPTTMeta: 
     parent_attr = 'folder' 
     order_insertion_by = ['order'] 

Ensuite, lorsque vous utilisez les django-MPTT méthodes de gestion et de ce fait, vous récupérerez un queryset de FolderItem s, et vous pouvez accéder à la Folder/Image pour chaque que vous itérer sur l'ensemble , à travers la clé étrangère générique. Cependant, sachez que cela sera probablement coûteux en termes de requêtes de base de données, puisque chaque fois que vous accédez à une clé étrangère générique, une nouvelle requête doit être émise.

Questions connexes