Search code examples
htmldjangodjango-templatesblock

How to insert multiple Django blocks into one template?


I am trying to use more different views in one template via different blocks or include method but I have got stuck. My aim is to implement my different views into one template. I tried to more solution but these haven't worked for me. I show these solution:

My views:

def  dashboard_data(request):
    # Here I collect data from my PostgreSQL database I push these into 
    #Objects and I send it to my test_a.html via render like below.

    return render(request, 'my_project/test_a.html', send_data)

def chart_data(request):
    #In these view my final goal is to collect data from database and create 
    #charts but for the simplicity I just use a list (a=[1,2,3,4]) and I 
    #push it to the test_b.html and I render it.


    render(request, 'my_project/test_b.html', send_data))

My templates:

1, base.html

<!DOCTYPE html>
<html lang="en">
<head>

  {% block title %}<title>My project</title>{% endblock %}
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- Include CSS files -->
  {% load static %}
  <!-- Include CSS files -->
  <link rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
  <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
  <link rel="stylesheet" href="{% static 'css/bootstrap-table.css' %}">
  <link rel="stylesheet" href="{% static 'css/styles.css' %}">
  <link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}">
</head>

<body>

     {% block sidebar %}

     {% endblock %}

     {% block content%}
     {% endblock %}

</body>
</html> 

1, test_a.html

  {% extends "monitor/base.html" %}

  {%block content%}

  {%for i in table%}
       <p> {{i.record}}</p>
  {%endfor%} 

  {%endblock}

2, test b.html

  {%for i in a%}
       <p> {{i}}</p>
  {%endfor}

So my goal would be that the test_b.html's result could appear in the base.html.

My solutions:

A: I tried to put into a block the test_b.html and integrate in the base.html

1, base.html (test1):

 {% block conent%}

 {% endblock %}

 {% block chart%}

 {% endblock %}

1, test_b.html (test1):

{% extends "monitor/base.html" %}

{%block chart%}    

{%for i in a%}
       <p> {{i}}</p>
{%endfor}

{%endblock%}

B: I tried to use {{ block.super }}

1, base.html (test1):

 {% block conent%}

 {% endblock %}

1, test_b.html (test1):

{% extends "monitor/base.html" %}

{%block content%}    
 {{ block.super }} 
{%for i in a%}
       <p> {{i}}</p>
{%endfor}

{%endblock%}

C: Finally I used include method too but I didn't work for me as well. Here I tried to use simple html tags like (<p>Hello world</p>) int the test_b.html and worked. So If I do not use variables it works but I have to use my variables from my views.

1, test_a.html

{% extends "monitor/base.html" %}

{%block chart%}    

{%for i in a%}
      <p> {{i}}</p>
{%endfor}

{%endblock%}
{% include "my_project/test_b.html" %} 

2, test_b.html

{%for i in a%}
     <p> {{i}}</p>
{% endfor %}

Solution

  • As @alessioferri20 mentioned, you cannot render 2 views at the same time. Basically, one view corresponds to one HTTP request & response.

    You can achieve what you want by using custom template tags: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/


    but I have to use my variables from my views.

    For example, chart_data could be an inclusion tag (https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#inclusion-tags), here is some pseudo-code:

    Let's say you want to show a chart for the age_stats from your view:

    def your_view(request, ...):
        age_stats = {...}
        ....
        return render(request, "template...", {'age_stats': age_stats})
    

    In your template:

    {% chart age_stats %}
    

    In your template tags:

    @register.inclusion_tag('path-to/chart.html')
    def chart(input_data):
        # collect data from database & use the input_data coming from your view
        data = ...
        return {'data': data}