2014-12-02 95 views
2

我有三种模型:节点,链接和路径。链接是两个节点之间的关系,路径是节点列表。我试图覆盖路径保存功能来创建路径中所有相邻节点之间的链接。我在Path模型中编写了一个add_link函数,并在路径模型的save函数中为所有相邻的对调用它。虽然Path正常保存,并且我可以使用控制台中的add_link函数创建链接,但它们不会在Path的保存功能中创建。我错过了什么?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年前,这是an issue与具有一定哈克修复管理M2M ......我还没有发现,如果有更好的东西现在虽然。

回答

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 

下面是测试我通过shell跑......

>>> 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>] 

正如你所见,链接对象从一个空列表开始,在针对PathNodeRelationships设置的Path对象运行保存后被填充。

+0

嗨,谢谢你的帮助!你是对的,当我调用path.save()时,它在shell中工作 - 当我从管理员保存时,它似乎只是不保存链接。任何想法为什么 - 管理员不会因为某种原因调用保存功能? – user3234309 2014-12-02 20:06:17

相关问题