将变量推送到模板的最佳做法是什么?

时间:2018-05-09 11:40:09

标签: python django python-3.x django-templates

我正在编写一个Web应用程序,并想知道将变量推送到模板的最佳做法是什么。现在,我在视图中请求模型,然后将这些对象推送到模板。

示例:

我有一个附加到这些框架的框架和控件。如果我想显示特定框架的所有控件,我会这样做。

型号:

# models.py
class Framework(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(null=True)


class Control(models.Model):
    title = models.CharField(max_length=250)
    description = models.TextField()
    framework = models.ForeignKey(Framework,
                                on_delete=models.CASCADE,
                                verbose_name="related framework")
    category = models.ForeignKey(FrameworkCat,
                             on_delete=models.CASCADE,
                             verbose_name="related category",
                             null=True)

观点:

# views.py
def show_frameworks(request):
    frameworks = Framework.objects.all()
    controls = Control.objects.all()

    data['frameworks'] = frameworks
    data['controls'] = controls

   return render(request, 'show_frameworks.html', data)

然后在模板中:

# templates/show_frameworks.html
<div>
{% for framework in frameworks %}
    <p>{{framework.name}}</p>
    {% for control in controls %}
        {% if control.framework == framework %}
            <p>{{control.title}}</p>
        {% endif %}
    {% endfor %}
{% endfor %}
</div>

这样做是否有效,或者更快/更高效地做这样的事情:

# views.py
def show_frameworks(request):
    controls = Control.objects.all().order_by('framework')

    data['controls'] = controls

   return render(request, 'show_frameworks.html', data)

然后在模板中:

# templates/show_frameworks.html
<div>
{% for control in controls %}
    {% if forloop.first %}
        <p>{{control.framework.name}}</p>
        <p>{{control.title}}</p>
        {% with prevframework = control.framework %}
    {% else %}
        {% with curframework = control.framework %}
        {% if curframework != prevframework %}
            <p>{{control.framework.name}}</p>
            <p>{{control.title}}</p>
       {% else %}
            <p>{{control.title}}</p>
       {% endif %}
    {% with prevframework = control.framework %}
    {% endif %}
{% endfor %}
</div>

这看起来有点复杂但意味着我必须向数据库发送较少的查询并将数据发送到模板。这是一个简单的例子,但在我的Web应用程序中,我有一个非常大的数据库,在慢速托管,所以任何时间优化都是受欢迎的。我的问题基本上是:后者会更有效率,因为只使用一个for循环,只有一个查询被发送到数据库?或者前者仍然更高效,尽管使用了两个for循环,多次循环每个控件并向数据库发送两个查询?

谢谢!

1 个答案:

答案 0 :(得分:3)

将尽可能多的逻辑移动到DB / plain Python。

您可以使用prefetch_related为每个<component-A someProp="Some text and <component-B/>"/> 获取相关的controls,并使用普通Python进行加入。不要在模板中放太多,因为模板引擎比普通的Python要慢,而且如果你有太多的话,你的代码可维护性较差:

framework

然后:

def show_frameworks(request):
    frameworks = Framework.objects.prefetch_related('control_set').all()
    data['frameworks'] = frameworks
    return render(request, 'show_frameworks.html', data)