2014-12-02 2 views
2

У меня есть три модели: узел, ссылка и путь. Ссылка - это связь между двумя узлами, а путь - список узлов. Я пытаюсь переопределить функцию сохранения пути, чтобы создать ссылку между всеми соседними узлами в пути. Я написал функцию add_link в модели Path и вызываю ее в функции сохранения в модели Path для всех смежных пар. Хотя путь правильно сохраняется, и я могу создавать ссылки с помощью функции 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() 

** Edit: ссылки создаются при вызове path.save() в консоли, но они не при использовании интерфейса администратора. Вот как я делаю администратор. **

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

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

второй править: Похоже, около 3-4 лет назад это было an issue с админ M2M, который имеет некоторые Hacky исправления ... Я не нашел, если есть что-нибудь лучше, в настоящее время, хотя.

ответ

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 перешли из пустого списка в заполнитель после запуска сохранения с объектом Path, у которого установлен некоторый набор PathNodeRelationships.

+0

Привет, спасибо за помощь! Вы правы, он работает в оболочке, когда я вызываю path.save() - кажется, что я не сохраняю ссылки только при сохранении с admin. Любая идея - почему администратор не вызывает функцию сохранения по какой-то причине? – user3234309

Смежные вопросы