2012-05-30 5 views
3

장고 내에 트리 구조를 모델링하려고합니다. 이것은 내가 가지고있는 것의 축소 된 버전입니다.Django 모델 : 루트 노드가 저장되지 않은 노드에 자식으로 나타납니다.

지금까지 그렇게 좋았습니다. 그것은 작동합니다. 하지만 지금과 같은 계층 구조를 만들기 위해 시작하는 경우 :

from ....models import Node 
root = Node() 
root.name = "ROOT" 
root.parent = None 
root.save() 

n = Node() 
print n.child_cnt() 
>> 1 
print n.node_set.all() 
[<Node: ROOT>] 

그래서 루트 노드가 n 내 자식으로 무엇을 만드는가를? 어떻게 피할 수 있습니까?

n.save()을 호출하면 문제가 사라지지만 관리 사이트 내에서 child_cnt으로 초기화 된 노드를 보는 것은 좋지 않습니다.

+0

위의 코드를 테스트했으며 child_cnt()는 0을 나타내며 node_set.all()은 []을 반환합니다. 나에게 그것은 특정 모델이나 앱에서 모델에 몇 가지 변경을 가하는 코드가있어 모델을 변경하는 것처럼 보입니다. – Tisho

+0

힌트를 보내 주셔서 감사합니다. 위의 코드에서 root.save()를 추가하는 것을 잊었습니다. 나는 그것을 바로 잡았다. 내 컴퓨터에서 실행은 이제 새로운 Django 프로젝트에 대해서도 말한 것처럼 동작합니다. – Qlaus

답변

1

나는 미친 소리가 나는 것을 알고있다. 그러나 나는 당신의 문제를 해결하려고 노력했다. 그리고 그것은 내가 시도한 어떤 시도에서도 작동하지 않았다. 어쨌든, Tree ForeignKey의 경우,이 유형의 키를 처리하는 전체 라이브러리 인 온라인 솔루션을 찾을 수 있습니다. https://github.com/django-mptt/django-mptt 실전에서 사용해 볼 수 있습니다. 나는 그런 작은 일을 위해 도서관을 추가해야하는 것을 싫어하지만, 나는 더 나은 것을 찾을 수 없었다.

또한 전체 lib를 가져 오지 않으려면 코드에 TreeForeignKey 만 가져올 수 있습니다.

+0

도서관에서 한 번 보았는데 다른 문제를 해결 한 것으로 보이므로 어쨌든 가져올 것입니다. 힌트를 가져 주셔서 감사합니다! – Qlaus

1

좋아, 몇 가지 조사 후 - 여기 결과입니다 : - : 그럼 https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey

재귀 관계와 외래 키 사용하는 경우, 대신 클래스 이름의 '자기'를 사용한다

첫째, 메모 - ForeignKey는 OneToOne 관계입니다. 부모 노드를 열거하는 동안 Node 자식을 열거하는 것은 올바르지 않습니다 ... 위로 Node_objects.all()로 실행되는 것으로 보이는 node_set.all()을 호출하면 그 이유는 무엇입니까? 새로 생성 된 Node 인스턴스에 대한 항목을 표시합니다 (DB에 저장되지 않음). 사실 node.node_set은 노드에 대한 외래 키를 가져 오기 위해 여기에 사용할 수 없습니다. 노드에 여러 아이를 가질하기 위해 - 당신이 ManyToManyField를 사용해야합니다, 예를 들면 :

children = models.ManyToManyField('self', null=True) 

한 다음 사용하여 호출 :

node.children.all() # for all children 

또는

node.children.count() 

편집를 :

간략한 분석 :

,
class A(model): 
    parent = ForeignKey(B) 

다음

a = A() 
b = B() 
b.parent_set.all() 

모든 부모로서 B를 가진, 또는 모든 A의 것을 가지고 PARENT_ID = b.id.를 반환합니다 귀하의 경우에는, 당신은 실제로 있습니다

a = A() 
b = A() 
b.parent_set.all() 

이 돌아갑니다 (A ==) 부모로서 B를 가지고 있으며,이 경우 a.parent_id = b.id에서, 그러나 아무도 b.id없는 모든 A의 (안 저장 됨), 따라서 parent_id = None 인 모든 노드 (b)를 얻을 수 있습니다.

실제로이 동작은 비 재귀 관계에서도 동일합니다. 첫 번째 예에서는 A()가 parent = None으로 저장되어 있고 저장되지 않은 B의 경우 b.parent_set.all()에 저장됩니다.

+0

첫 번째 : '자체'힌트를 보내 주셔서 감사합니다. 나는 그것을 몰랐다. – Qlaus

+0

두 번째 : node_set.all()이 objects.all()으로 실행되지 않습니다. parent = root와 함께 세 번째 노드를 추가하고 저장하십시오. node_set을 요청할 때 여전히 루트 노드 만 가져올 것입니다. 셋째 : ForeignKey는 ** many-to-one ** 관계입니다. 어쨌든 : ManyToManyFields를 살펴 보겠지만 이상하게 느껴질 것입니다. 각 노드마다 단 하나의 부모가 있어야하기 때문입니다. 그렇다면 다 대일 관계를 사용하지 않는 이유는 무엇입니까? – Qlaus

+0

예, 정확히 objects.all()과 같지 않지만 objects.filter (pk = 없음)와 같습니다. 일반적으로 many-to-one에 동의하지만 여기서는 이상하게 사용됩니다 ... 현재 노드의 부모에 대한 노드 계산 ... 불가능하지는 않지만 문제를 일으키는 것으로 보입니다. 부모님 대신 노드에 자식을 두는 것이 좋습니다. 결국 그것은 당신이 여기 찾는 어린이 수입니다. – Tisho

관련 문제