Django multiple template rendering

10,286

Solution 1

You're labouring under a misapprehension of how the Django template language works- By default Django takes a Request, relays it (via the urls in your urls.py) to the View, which can take the data from the request, and render a Template- the result of which is the HTML from your template.html page interpolated with the context information that you passed to the rendering- as a Response to the browser, which displays the HTML as a page.

The template rendering happens server side- once it's been returned as a Response, Django templates no longer have any control over what is displayed client side. The Django template language is used to determine what will be rendered to the Response but after Template rendering, it doesn't exist on the page anymore and can't be used to modify what's displayed client-side. For that you need Javascript.

Javascript and it's various permutations is what people use to provide client-side interactivity to a webpage In your example, a Javascript event would fire when the user selects a recipe, and could place an AJAX call back to your server which would fetch that specific recipe information.

I recommend doing some more advanced reading into APIs (A good starting point is Django Rest Framework, which has an in-depth tutorial) and making API calls. And possibly look into Single Page Apps (SPAs) and Django tutorials, as that sounds like what you're trying to achieve.

Solution 2

You can work with multiple "cascaded" templates!

Make the first template with all needed extends, like you did it:

<body>
{% block extend1 %}
{% endblock %}

{% block extend2 %}
{% endblock %}

{% block extend3 %}
{% endblock %}
</body>

Then make a second template like this:

{% extends "template1.html" %}
{% block extend1 %}
Filling this with content.....
{% endblock %}

{% block extend2 %}
{% endblock %}

{% block extend3 %}
{% endblock %}

And a third one:

{% extends "template2.html" %}
{% block extend2 %}
filling another block with content.....
{% endblock %}

{% block extend3 %}
{% endblock %}

...and so on. I have used this for adding a menu! On some pages I might need the menu, on other pages not - so depending on what kind of page I need (with or without menu), I end up extending version 1 or version 2 (or which one ever).

But you haven't clarified what kind of content you wanted to place into those parts. So my solution might not be appropriate. It's just the solution to the problem I had with the menu - it's some kind of "multi template rendering", solved with extension (or inheritance).

Share:
10,286
Jeroen Groeneveld
Author by

Jeroen Groeneveld

Currently learning Python and Django by writing a website. Its a real arduous task for a beginner but I'm having fun and it keeps me motivated. However, sometimes I do have some questions and I come to StackOverflow.

Updated on June 27, 2022

Comments

  • Jeroen Groeneveld
    Jeroen Groeneveld almost 2 years

    At the moment I'm working on a pretty complex page that needs to be updated when a user selects a recipe that is displayed on the page.Upon selection of a recipe, the price and the name of the recipe need to be displayed on the page.

    My thought is to render multiple extend/include templates that are each responsible for their own part of the webpage.However, I face a few problems:

    1. I need multiple view functions to process data for all templates.
    2. I need to pass the request to multiple view functions so that they return the template with the correct data
    3. One of the functions not only takes the request but also the slug of a model object to update data on the page.

    Questions:

    1. How do I send responses/data from different view functions to each other?
    2. How do I pass the request to multiple functions?
    3. Does the rendering of the extends also make sure that the base.html is rendered?
    4. Are extends the right thing to use or should I use includes?

    So far I have thought of this system:

    base.html

    <body>
        {% block extend1 %}
        {% endblock %}
    
        {% block extend2 %}
        {% endblock %}
    
        {% block extend3 %}
        {% endblock %}
    </body>
    

    extend1.html (example for the 3 extends)

    {% extends base.html %}
    
    {% block extend1 %}
        #html code
    {% endblock
    

    views.py

    def extend1(request):
        #do something
        template = 'extend1.html' 
        context = a, b, c
        return render(template.render(context))
    
    def extend2(request):
        #do something
        template = 'extend2.html' 
        context = d, e, f
        return render(template.render(context))
    
    def extend3(request, slug):
        #do something
        template = 'extend3.html' 
        context = g, h, i
        return render(template.render(context))
    
  • bruno desthuilliers
    bruno desthuilliers over 6 years
    I'm not sure I'd recommand DRF to someone who obviously didn't even took time to understand the most basic Django feature, which is how the HTTP request/response is handled.
  • ptr
    ptr over 6 years
    The intention is to furnish the OP with the context that he's lacking ("how do people make websites that can be updated dynamically client side?"). I think the tutorials in DRF and using SPAs with Django will go a long way towards demonstrating where his misunderstanding was
  • Jeroen Groeneveld
    Jeroen Groeneveld over 6 years
    Peter, thanks for your time to answer my question! In hindsight I realize I did not fully understand the concepts I was working with. You have put me on the right track though since I have previously managed to get it working. My, obviously wrong, thought was that I needed to make my code prettier or more DRY. This was a misconception on my part which led to this admittedly not so good question. Thanks anyway! I hope to come to SO in the future with more informed questions.