【问题标题】:Django: Creating and saving another model in a save overrideDjango:在保存覆盖中创建和保存另一个模型
【发布时间】:2015-01-31 02:44:48
【问题描述】:

我有三个模型:节点、链接和路径。链接是两个节点之间的关系,路径是节点列表。我正在尝试覆盖路径保存功能以在路径中的所有相邻节点之间创建链接。我在 Path 模型中编写了一个 add_link 函数,并在 Path 模型中的 save 函数中为所有相邻对调用它。虽然路径保存正确,并且我可以使用控制台中的 add_link 函数创建链接,但它们并没有在路径的保存函数中创建。我错过了什么?

以下是模型:

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)

第二次编辑:看起来大约 3-4 年前这是 an issue 管理员 m2m 有一些 hacky 修复...不过我还没有发现现在是否有更好的东西。

【问题讨论】:

    标签: django


    【解决方案1】:

    我不确定你可能出了什么问题,因为当我测试你的代码时它可以工作。

    对于它的价值,一个建议是让这段代码更优雅一点......

        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 对象运行保存后,Link 对象从一个空列表变为被填充。

    【讨论】:

    • 您好,感谢您的帮助!你是对的,当我调用 path.save() 时,它确实在 shell 中工作——当我从管理员保存时,它似乎只是没有保存链接。知道为什么 - 管理员出于某种原因不调用保存功能吗?
    猜你喜欢
    • 2018-10-07
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2011-08-17
    • 2018-07-26
    相关资源
    最近更新 更多