2014-12-02 3 views
2

노드, 링크 및 경로의 세 가지 모델이 있습니다. 링크는 두 노드 사이의 관계이며 경로는 노드 목록입니다. 경로에있는 모든 인접한 노드 사이의 링크를 만들려면 경로 저장 함수를 재정의하려면 노력하고있어. 나는 경로 모델에 add_link 함수를 작성하고 모든 인접한 쌍에 대한 경로 모델의 저장 함수에서이를 호출하고 있습니다. 경로가 제대로 저장되어 있지만 콘솔에서 add_link 함수를 사용하여 링크를 만들 수는 있지만 경로 저장 기능에서 만들어지지 않습니다. 내가 뭘 놓치고 있니?Django : 저장 오버라이드에서 다른 모델 만들기 및 저장

다음은 모델입니다 :

class Node(models.Model): 
    title = models.CharField(max_length=200, blank=True) 
    links = models.ManyToManyField('self', through='Link', 
              symmetrical=False, 
              related_name='related_to+') 
    def add_link(self, other, symm=True): 
     link, created = Link.objects.get_or_create(
      from_node=self, 
      to_node=other) 
     if symm: 
      # avoid recursion by passing `symm=False` 
      other.add_link(self, False) 
     return link 

class Link(models.Model): 
    from_node = models.ForeignKey(Node, related_name="from") 
    to_node = models.ForeignKey(Node, related_name="to") 

class Path(models.Model): 
    nodes = models.ManyToManyField(Node, related_name="nodes",through='PathNodeRelationship') 

    def save(self, *args, **kwargs): 
     super(Path, self).save(*args, **kwargs) 

     # save all not-existent links on this path 
     nodes = self.nodes.all() 
     if nodes: 
      f = nodes[0] 
      i = 1 
      while i < len(nodes): 
       s = nodes[i] 

       f.add_link(s) 
       f = s 
       i += 1 

class PathNodeRelationship(models.Model): 
    node = models.ForeignKey(Node) 
    path = models.ForeignKey(Path) 
    order_index = models.IntegerField() 

** 편집 : 링크가 콘솔에서 path.save()를 호출 할 때 생성되지만,이 관리 인터페이스를 사용하지 않을 때. 이것이 제가 관리자를하는 방법입니다. **

class NodeInline(admin.TabularInline): 
    model = Path.nodes.through 
    extra = 1 

class PathAdmin(admin.ModelAdmin): 
     inlines = (NodeInline,) 
admin.site.register(Path, PathAdmin) 

2 편집 : 요즘하지만 더 나은 아무것도가 있다면 주위 3~4년 전에이 일부 해키 수정이 관리 M2M와 an issue처럼 보이는 ... 나는 발견하지 않았습니다.

답변

3

내가 코드를 테스트 할 때 작동하지 않을 수 있습니다. 그것은 가치가 무엇인지에 대한

, 하나 추천하지만 ... 여기

def save(self, *args, **kwargs): 
     super(Path, self).save(*args, **kwargs) 

     # save all not-existent links on this path 
     previous_node = None 
     for node in self.nodes.all(): 
      if previous_node is not None: 
       previous_node.add_link(node) 
      previous_node = node 

내가 쉘을 통해 실행 테스트입니다 ...이 코드를 좀 더 우아하게하는 것입니다

>>> Link.objects.all() 
[] 
>>> path = Path.objects.get(id=2) 
>>> path.save() 
>>> Link.objects.all() 
[<Link: Link object>, <Link: Link object>, <Link: Link object>, <Link: Link object>, <Link: Link object>, <Link: Link object>] 

보시다시피 Link 객체는 PathNodeRelationships가 설정된 Path 객체에 대한 저장을 실행 한 후 빈 목록에서 채워집니다.

+0

안녕하세요, 귀하의 도움에 감사드립니다. 네가 맞아, 내가 path.save()를 호출했을 때 쉘에서 작동한다. 관리자가 저장할 때 링크를 저장하지 않는 것 같다. 모든 이유는 - 관리자가 어떤 이유로 저장 함수를 호출하지 않는 이유는 무엇입니까? – user3234309