2013-03-18 12 views
6

Chcę mieć model z 2 polami, dziećmi i rodzicem. Jak to zrobić w django? Mam coś takiegoTworzenie struktury drzewa w modelach django?

from django.db import models 
class FooModel(models.Model) 
    parent = models.ForeignKey('self', blank=True, null=True) 
    children = models.ManyToOneRel('self', blank=True, null=True) 

    def __init__(self, *args, **kwargs): 
     super(FooModel, self).__init__(*args, **kwargs) 
     self.parent.children.add(self) 

Ale nie sądzę, mam używać ManyToOneRel tak (szczególnie, bo to daje mi błąd kluczowego na „puste”). Jakakolwiek rada?

+5

https://github.com/django-mptt/django-mptt/ – dm03514

+1

https://tabo.pe/projects/django-treebeard/docs/1.61/api.html – andrefsp

+0

Są to zarówno dobre, ale jest to można to zrobić bezpośrednio w takich dziedzinach, jak próbuję zrobić powyżej? Wolałbym nie włączać w to innej zależności i nie dbam o wydajność w tym przypadku. – sfendell

Odpowiedz

17

ManyToOneRel to wewnętrzna klasa implementacji, nie jest przeznaczona do użytku w modelach.

Ale dlaczego myślisz, że i tak tego potrzebujesz? Jak szczegółowo wyjaśnia dokumentacja, podczas definiowania klucza obcego automatycznie uzyskuje się odwrotną relację. Więc w twoim przypadku, jeśli zdefiniujesz parent następnie automatycznie uzyskać self.foomodel_set już: można uczynić go jeszcze bardziej wyraźny przy użyciu parametru related_name:

parent = models.ForeignKey('self', blank=True, null=True, related_name='children') 

Zauważ, że jeśli planujesz robić skomplikowane rzeczy z drzewami prawdopodobnie chcesz używać biblioteki django-mptt.

0

nie mogłem znaleźć w dokumentacji ManyToOneRel więc spojrzałem w górę code for it:

def __init__(self, to, field_name, related_name=None, limit_choices_to=None, 
     parent_link=False, on_delete=None): 

Jak widać, nie ma blank argumentem.

+0

W porządku, już to rozgryzłem. Zastanawiam się, co powinienem użyć zamiast tego. – sfendell

+0

może po prostu użyć CharField do przechowywania kluczy dzieci i niestandardowej metody lub właściwości, aby utworzyć ich na żądanie? –

2
class FooModel(models.Model) 
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children') 


FooModel.objects.get(pk=1).children.all() 

Jeśli chcesz buforować korzystania cokolwiek chcesz: buforowanie zapytania gdzieś przechowywać wszystkie dzieci w dominującej w postaci płaskiej listy PKS, ale nie zapomnij, aby obsłużyć nowe podmioty do aktualizacji tej listy. ManyToOneRel służy do wewnętrznych potrzeb django, ponadto nie jest instancją klasy Field.

Powiązane problemy