【问题标题】:Bootstrap accordion with Django: How to only load the data for the open accordion section?使用 Django 引导手风琴:如何仅加载打开的手风琴部分的数据?
【发布时间】:2017-02-25 22:26:36
【问题描述】:

我正在尝试制作一个网页,以像这样 (see here) 的引导手风琴格式显示食谱。 这就是我现在的做法:

<div class="panel-group" id="accordion">
    {% for recipe in recipes %}
    <div class="panel panel-default">
        <div class="panel-heading">
            <h4 class="panel-title">
                <a data-toggle="collapse" data-parent="#accordion" href="#collapse{{ forloop.counter }}">
                    {{ recipe }}
                </a>
            </h4>
        </div>
        <div id="collapse{{ forloop.counter }}" class="panel-collapse collapse">
            <div class="panel-body">
                <table class="table table-hover">
                    {% for ingredient in  foodtype|ingredients_in_recipe:recipe %}
                        <tr>
                            <td>
                                {{ ingredient.ingredient_name }}
                            </td>
                            <td>
                                {{ ingredient.ingredient_quantity }}
                            </td>
                        </tr>
                    {% endfor %}
                    <p>{{ recipe.details }}</p>
                </table>
            </div>
        </div>
    </div>
    {% endfor %}
</div>

我为此制作了一个自定义模板标签,如下所示:

@register.filter
def ingredients_in_recipe(foodtype, recipe):
    return foodtype.ingredient_set.filter(recipe=recipe).order_by("ingredient_name")

问题是我有 200 多个食谱,加载所有这些数据太慢了。理想情况下,模板标签函数成分_in_recipe 应该只在用户点击食谱时被调用。但是据我了解,这是不可能的,因为 Django 会运行​​它,然后将呈现的 HTML 发送给用户。

无论如何我可以在保持手风琴风格的同时避免这个问题吗?

提前致谢, 最大

编辑:这也是我的看法

def detail(request, foodtype_id):
     foodtype = get_object_or_404(foodtype, id=foodtype_id)
     recipe = foodtype.recipe_set.values_list('recipe').order_by('recipe').distinct()
     context = {
         'foodtype': foodtype,
         'recipe': recipe,
     }
     return render(request, 'main/detail.html', context)

【问题讨论】:

    标签: python django twitter-bootstrap django-templates templatetags


    【解决方案1】:

    最好在到达模板之前执行该逻辑。如果您设置成分的顺序,那么您就不必在模板中订购它们了?这是否有效并提高了性能?

    class Ingredient(models.Model):
      ...
    
      class Meta:
        ordering = ['ingredient_name']
    
    
    <div class="panel-group" id="accordion">
        {% for recipe in recipes %}
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#collapse{{ forloop.counter }}">
                        {{ recipe }}
                    </a>
                </h4>
            </div>
            <div id="collapse{{ forloop.counter }}" class="panel-collapse collapse">
                <div class="panel-body">
                    <table class="table table-hover">
                        {% for ingredient in recipe.ingredient_set.all %}
                            <tr>
                                <td>
                                    {{ ingredient.ingredient_name }}
                                </td>
                                <td>
                                    {{ ingredient.ingredient_quantity }}
                                </td>
                            </tr>
                        {% endfor %}
                        <p>{{ recipe.details }}</p>
                    </table>
                </div>
            </div>
        </div>
        {% endfor %}
    </div>
    

    【讨论】:

    • 我忘了在 order_by 之后添加 .distinct()。我需要它,因为某些成分可能会重复,但把它放在那里会使网页比没有它慢得多。想法?
    • 你能发表你的看法,让我看看你用什么方法得到recipes
    • 问题是抓取related_name_set 会进行数据库调用。此解决方案可能会有所帮助,但要真正提高性能,您需要摆脱额外的 db 调用。尝试类似stackoverflow.com/questions/2532686/…
    • 这很有见地。看起来我做了太多的数据库调用,我需要一个与 select_related 等效的反向关系。我相信这是prefetch_related?这会在我看来吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2023-01-03
    • 2011-10-20
    • 2018-11-01
    • 1970-01-01
    相关资源
    最近更新 更多