Home > database >  Django: Create a dynamic sidebar template and use it in other templates
Django: Create a dynamic sidebar template and use it in other templates

Time:12-07

NOTE: This question is not about creating or using a base template!

I'm creating a products app in my project, using only django and html/css, and all pages in this part has a sidebar nav menu that categorizes different product models and types. So this sidebar will be used in all other product pages.

Here is my views.py file:

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)

And the sidebar template is as shown below:

  <ul >
    {% for usage_item in usage_queryset %}
      <li >
        <a href="#" 
           data-bs-toggle="collapse"
           data-bs-target="#usage_{{ usage_item.usage_name_fa }}">
           <i ></i>
            الکتروپمپ‌های {{ usage_item.usage_name_fa }}
        </a>
        <ul  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 >
                <a href="#" >
                  {{ sub_usage }}
                </a>
              </li>
            {% endif %}
          {% endfor %}
        </ul>
      </li>
    {% endfor %}
  </ul>

And now I'm creating a proucts main page for example, which should implement this sidebar. I included this sidebar template in my products page template as shown below:

    <section>
        <div >
            <div >
                <div >
                    {% include "products/products_sidebar.html" %}
                </div>
                <div >
                    content
                </div>
            </div>
        </div>
    </section>

Now, I know that without a URL, the view sidebar_data() won't be called, and for now my urls are as shown below:

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

And as expected, context data sent in the sidebar_data() view, will not be sent and so my sidebar will not be populated with the data. How am I supposed to acheive this? There is one way, in which I have to send the queryset data sent to sidebar in all the different product pages, but I think there should be a more sufficient way. Your help is appreciated in advance.

CodePudding user response:

To achieve this you need to pass the same context in your all views. A simple demonstration of your views would be as follows:

views.py

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

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

  • Related