Django的引导手风琴:如何只加载打开手风琴节的数据?

时间:2022-12-01 14:53:19

I'm trying to make a webpage that will display recipes in the format of a bootstrap accordion like so (see here). This is how I'm doing it as of now:

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

<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>

I have made a custom template tag for this like so:

我为此做了一个自定义模板标签如下:

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

The problem is that I have 200+ recipes and loading all this data is way too slow. Ideally the template tag function ingredients_in_recipe should only be called when the user clicks on the recipe. However from my understanding this isn't possible because Django runs it all then sends the rendered HTML to the user.

问题是,我有200多个食谱,而且加载所有这些数据太慢了。理想情况下,只有当用户单击菜谱时,才应该调用template tag函数配料s_in_recipe。然而,从我的理解来看,这是不可能的,因为Django运行它,然后将呈现的HTML发送给用户。

Is there anyway I could circumvent this issue whilst still keeping the accordion style like in the picture?

我能不能绕过这个问题,同时保持手风琴的风格?

Thanks in advance, Max

谢谢你提前,马克斯

EDIT: Here's my view as well

编辑:这也是我的观点。

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)

1 个解决方案

#1


1  

Always better to do that logic before it gets to the template. What if you set the ordering on ingredients so then you won't have to order them in the template? Does that work and improve the performance?

最好在它到达模板之前执行这个逻辑。如果你在原料上设置了顺序,这样你就不用在模板中对它们进行排序了。这样做能提高性能吗?

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>

#1


1  

Always better to do that logic before it gets to the template. What if you set the ordering on ingredients so then you won't have to order them in the template? Does that work and improve the performance?

最好在它到达模板之前执行这个逻辑。如果你在原料上设置了顺序,这样你就不用在模板中对它们进行排序了。这样做能提高性能吗?

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>