Django ManyToManyField引用自己:渲染到模板

时间:2018-10-12 23:34:52

标签: python django django-models django-templates django-views

下面是我正在处理的项目的代码。正如您在视图中看到的那样,我正在运行一个查询,以查询风险模型中与Url中的主键相关联的对象。

问题是我无法访问要查询的对象的属性。

模型

class Risk(models.Model):
    risk_title = models.CharField(max_length=60)
    root_causes = models.ManyToManyField('self',
                                         through='Roots',
                                         symmetrical=False,
                                         related_name='root_cause')


class Roots(models.Model):
    causal_risk = models.ForeignKey(Risk, related_name='causes', on_delete=models.CASCADE)
    effected_risk = models.ForeignKey(Risk, related_name='effected_risk', on_delete=models.CASCADE)

查看:

def view_risk(request, id):

    try:
           risk = Risk.objects.get(pk=id)
    except Risk.DoesNotExist:
           raise Http404("Risk does not exist")

       roots = Roots.objects.filter(effected_risk=id)


    args = {
        'risk': risk,
        'roots': roots,
       }
return render(request, 'risks/risk_detail.html', args)

模板:

{% for root in roots %}

{{ root }}

{% endfor %}

运行上面的代码将返回以下内容:

Roots object (2) Roots object (3)

这应该是可以预期的,因为这些是我通过管理界面对模型所做的输入。

但是,当我跑步时:

{% for root in roots %}

{{ root.risk_title }}

{% endfor %}

屏幕空白。

TLDR 将查询从中介表传递到模板是可行的,但是模板无法访问对象属性。如何运行上面的查询,然后访问模板中的对象?

已更新,其中包含JoJo响应中的渲染部分。我的其他更新已解决了此问题。

提前谢谢!

2 个答案:

答案 0 :(得分:1)

请注意,视图函数缺少return语句,因此实际上根本没有呈现html页面。

假设模板html命名为'my_template.html',则丢失的return应该类似于:

def view_risk(request, id):
    # ...
    return render(request, 'my_template.html', args)

进一步,如@JonHrovat所述,模板需要调用

{{ root.causal_risk.risk_title }}

在for循环中。

效率说明

如果您使用当前对root.causal_risk.risk_title的查询在模板内调用roots,则会导致其他查询,每次迭代一次。在视图函数中查询根时,可以通过使用select-related语句来避免这种情况:

roots = Roots.objects.select_related('causal_risk__risk_title').filter(effected_risk=id)

答案 1 :(得分:1)

我忘记了查询模型的直接属性。使用此模板,我得到了所需的东西:

{% for root in roots %}

{{ root.causal_risk.risk_title }}

{% endfor %}