【问题标题】:What is the best practice for pushing variables to templates?将变量推送到模板的最佳实践是什么?
【发布时间】:2018-05-09 11:40:09
【问题描述】:

我正在编写一个 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 循环,多次循环每个控件并向数据库发送两个查询?

谢谢!

【问题讨论】:

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


    【解决方案1】:

    将尽可能多的逻辑移至 DB/普通 Python。

    您可以使用prefetch_related 为每个framework 获取相关的controls 并在普通Python 中进行连接。不要在模板中放太多,因为模板引擎比普通 Python 慢,而且如果你有太多,你的代码可维护性较差:

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

    然后:

    <div>
    {% for framework in frameworks %}
        <p>{{framework.name}}</p>
        {% for control in framework.control_set %}
             <p>{{control.title}}</p>
        {% endfor %}
    {% endfor %}
    </div>
    

    【讨论】:

    • 我不知道 prefetch 和 select_related()。谢谢!但是,我没有 FK 来控制我的框架模型。控制模型确实有一个 FK 框架,因为这是一个多对一的关系。将我的模型添加到主帖中。你上面的例子会有什么变化?
    • @AlexanderSchillemans 我已经更新了答案。 Django默认为相关对象添加&lt;fieldname&gt;_set
    • 正是我需要的。标记为已回答。谢谢!
    猜你喜欢
    • 2012-08-19
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多