Django:创建一个动态侧边栏模板并在其他模板中使用它

oyjwcjzk  于 2022-12-14  发布在  Go
关注(0)|答案(1)|浏览(172)

注意:此问题与创建或使用基本模板无关!
我正在我的项目中创建一个products应用,只使用了django和html/css,这部分的所有页面都有一个侧边栏导航菜单,可以对不同的产品型号和类型进行分类,所以这个侧边栏将被用于所有其他产品页面。
下面是我的views.py文件:

from django.shortcuts import render

from .models import (
    Product,
    Usage,
    SubUsage,
    MainModel,
    PumpType,
    HeadFlowDataSet,
)

def products_usage_main(request):
    product_queryset = Product.objects.all()
    usage_queryset = Usage.objects.all()
    sub_usage_queryset = SubUsage.objects.all()
    main_model_queryset = MainModel.objects.all()
    pump_type_queryset = PumpType.objects.all()
    context = {
        "product_queryset": product_queryset,
        "usage_queryset": usage_queryset,
        "sub_usage_queryset": sub_usage_queryset,
        "main_model_queryset": main_model_queryset,
        "pump_type_queryset": pump_type_queryset,
    }
    return render(request, "products/products_usage_main.html", context)

def sidebar_data(request):
    usage_queryset = Usage.objects.all()
    sub_usage_queryset = SubUsage.objects.all()
    main_model_queryset = MainModel.objects.all()
    pump_type_queryset = PumpType.objects.all()
    context = {
        "usage_queryset": usage_queryset,
        "sub_usage_queryset": sub_usage_queryset,
        "main_model_queryset": main_model_queryset,
        "pump_type_queryset": pump_type_queryset,
    }
    return render(request, "products/products_sidebar.html", context)

侧边栏模板如下图所示:

<ul class="nav flex-column list-unstyled my-3 ms-3">
    {% for usage_item in usage_queryset %}
      <li class="nav-item p-2 ms-4">
        <a href="#" class="text-decoration-none nm-text-color fw-semibold"
           data-bs-toggle="collapse"
           data-bs-target="#usage_{{ usage_item.usage_name_fa }}">
           <i class="fa-solid fa-angle-left me-2 icon-selector"></i>
            الکتروپمپ‌های {{ usage_item.usage_name_fa }}
        </a>
        <ul class="submenu collapse" id="usage_{{ usage_item.usage_name_fa }}"
          data-bs-parent="#nav_accordion">
          {% for sub_usage in sub_usage_queryset %}
            {% if sub_usage.usage == usage_item %}
              <li class="my-2 ms-4">
                <a href="#" class="text-decoration-none nm-text-color fw-semibold">
                  {{ sub_usage }}
                </a>
              </li>
            {% endif %}
          {% endfor %}
        </ul>
      </li>
    {% endfor %}
  </ul>

现在我正在创建一个prouts主页,它应该实现这个侧边栏,我把这个侧边栏模板包含在我的产品页面模板中,如下所示:

<section>
        <div class="container-fluid">
            <div class="row">
                <div class="col-6 col-lg-4 px-0">
                    {% include "products/products_sidebar.html" %}
                </div>
                <div class="col-6 col-lg-8">
                    content
                </div>
            </div>
        </div>
    </section>

现在,我知道没有URL,视图sidebar_data()将不会被调用,现在我的URL如下所示:

urlpatterns = [
    path("application/", products_usage_main, name="products_usage_main"),
    path("application/<str:pk>", product_detail, name="product_detail"),
]

正如预期的那样,在sidebar_data()视图中发送的上下文数据将不会被发送,因此我的侧边栏将不会填充这些数据。我应该如何实现这一点?有一种方法,我必须将所有不同产品页面中发送到侧边栏的查询集数据发送出去,但我认为应该有一种更充分的方法。感谢您的帮助。

yhived7q

yhived7q1#

要实现这一点,您需要在所有视图中传递相同的上下文。视图的一个简单演示如下:
views.py

# Since these context will be common to all views it would be written outside any view function
def get_common_queryset():
    usage_queryset = Usage.objects.all()
    sub_usage_queryset = SubUsage.objects.all()
    main_model_queryset = MainModel.objects.all()
    pump_type_queryset = PumpType.objects.all()
    queryset_dictionary = {
        "usage_queryset": usage_queryset,
        "sub_usage_queryset": sub_usage_queryset,
        "main_model_queryset": main_model_queryset,
        "pump_type_queryset": pump_type_queryset,
    }
    return queryset_dictionary


# and in every other views
def products_usage_main(request):
    ...
    context_of_view = {
    ...
    }
    common_context = get_common_queryset()
    context = {**context_of_view, **common_context} # dictionary expansion
    return render(request, "template_name.html", context)

相关问题