2009-05-20 6 views
2

J'ai un modèle Django comme:Trouvez racines d'un grand nombre à plusieurs arbres de la catégorie dans Django

class Category(models.Model): 
    status=models.CharField(max_length=16) 
    machineName=models.CharField(max_length=50) 
    readableName=models.CharField(max_length=100) 
    description=models.CharField(max_length=1024) 
    parents=models.ManyToManyField('self') 

Où chaque catégorie peut exister dans de nombreux parents. Certaines catégories n'ont pas de parents, ce sont les catégories «racine». En langage SQL simple, je pourrais les trouver par:

SELECT "readableName" 
FROM foo_category AS c 
LEFT JOIN foo_category_parents AS cp ON (c.id=cp.from_category_id) 
WHERE cp.to_category_id IS NULL; 

Et en effet, cela fonctionne bien. Comment trouver la "liste des catégories sans parents" avec un appel Django-y? J'ai essayé:

# Says "Cannot resolve keyword 'is_null' into field." 
Category.objects.filter(parents__is_null=True) 
# Says "Join on field 'id' not permitted." 
Category.objects.filter(parents__pk_null=True) 

Mais comme indiqué, aucun travail.

Répondre

7

Les champs plusieurs-à-plusieurs de Django fonctionnent normalement de façon symétrique (voir entry in the Django docs). Quand vous faites un ManyToMany à vous-même, cela signifie qu'une entrée ManyToMany inverse sera créée, donc en fait chaque catégorie avec un parent sera le parent du parent (si cela a du sens).

En d'autres termes:

a = Category.objects.create(name='a') 
b = Category.objects.create(name='b') 
b.parents.add(a) 

print b.parents.all() # produces [a] 
print a.parents.all() # produces [b], which is why your filter is failing 

Pour contourner ce problème, il y a une option spéciale:

class Category(models.Model): 
    # ... as above ... 
    parents=models.ManyToManyField('self', symmetrical=False) 

Maintenant vous pouvez obtenir les catégories parentes avec:

Category.objects.filter(parents=None) 
+0

Magnifique merci , "symmetrical = False" et "parents = None" est exactement ce dont j'ai besoin. Et bien sûr, "parents = aucun" est une meilleure syntaxe que mes échecs! – arantius