Search code examples
pythondjangodjango-viewsdjango-templatesdjango-4.1

Django Template Inheritance Issue: {% if %} Block Not Rendering When Extending base.html


Problem Description

I'm working on a Django project where I have a form that, when submitted, calculates some results and displays them on the same page. The issue arises when I use a base template (base.html). Without using base.html, everything works perfectly, and the results are displayed correctly. However, when I extend from base.html, the content within the {% if results %}{% endif %} block in my test.html template doesn't get displayed at all.

base.html

Here is my base.html:

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}AbiturTest{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/style.css' %}">
    <link rel="icon" type="image/x-icon" href="{% static 'main/img/icon.ico' %}">
    <link rel="apple-touch-icon" href="{% static 'main/img/icon.png' %}">
    <link rel="shortcut icon" href="{% static 'main/img/icon.ico' %}">
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="{% url 'home' %}">Home</a></li>
                <li><a href="{% url 'test' %}">Test</a></li>
            </ul>
        </nav>
    </header>
    
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

test.html

Here is my test.html:

{% extends 'main/base.html' %}

{% block title %}Test - AbiturTest{% endblock %}

{% block content %}
    <h1>Тест AbiturTest</h1>
    <form id="test-form" method="post">
        {% csrf_token %}
        <ul>
            {% for question in questions %}
                <li>{{ question.text }}
                    <div class="radio-buttons">
                        <input type="radio" id="q{{ question.id }}_1" class="radio-button" name="answer_{{ question.id }}" value="1" required>
                        <label for="q{{ question.id }}_1" class="radio-label">Полностью не согласен</label>
                        <input type="radio" id="q{{ question.id }}_2" class="radio-button" name="answer_{{ question.id }}" value="2">
                        <label for="q{{ question.id }}_2" class="radio-label">Не согласен</label>
                        <input type="radio" id="q{{ question.id }}_3" class="radio-button" name="answer_{{ question.id }}" value="3">
                        <label for="q{{ question.id }}_3" class="radio-label">Нейтрально</label>
                        <input type="radio" id="q{{ question.id }}_4" class="radio-button" name="answer_{{ question.id }}" value="4">
                        <label for="q{{ question.id }}_4" class="radio-label">Согласен</label>
                        <input type="radio" id="q{{ question.id }}_5" class="radio-button" name="answer_{{ question.id }}" value="5">
                        <label for="q{{ question.id }}_5" class="radio-label">Полностью согласен</label>
                    </div>
                </li>
            {% endfor %}
        </ul>
        <button type="submit" id="submit-button" class="button" disabled>Отправить</button>
    </form>

    {% if results %}
    <div id="result-overlay" class="result-overlay">
        <h2>Результаты:</h2>
        <ul>
            {% for result in results %}
                <li>{{ result.profession }}: {{ result.percentage }}%</li>
            {% endfor %}
        </ul>
        <a href="{% url 'test' %}" class="button enabled">Пройти тест еще раз</a>
    </div>
    {% endif %}
{% endblock %}

views.py

Here is the view that processes the form and renders the test.html template:

from django.shortcuts import render
import json
from django.conf import settings

def home(request):
    return render(request, 'main/index.html')

def test(request):
    if request.method == 'POST':
        with open(settings.JSON_FILE_PATH) as f:
            data = json.load(f)
        questions = data['questions']
        relations = data['relations']
        
        total_scores = {profession['id']: 0 for profession in data['professions']}
        
        # Сбор ответов и расчет баллов
        for question in questions:
            question_id = question['id']
            answer = int(request.POST.get(f'answer_{question_id}'))
            for profession_id, relation in relations[str(question_id)].items():
                total_scores[profession_id] += answer * relation['relation']
        
        # Нормализация баллов для расчета процентов
        total_sum = sum(total_scores.values())
        percentages = {profession_id: (score / total_sum) * 100 for profession_id, score in total_scores.items()}
        
        results = [
            {"profession": next(profession['name'] for profession in data['professions'] if profession['id'] == profession_id), "percentage": percentage}
            for profession_id, percentage in percentages.items()
        ]
        
        return render(request, 'main/test.html', {'questions': questions, 'results': results})
    
    else:
        with open(settings.JSON_FILE_PATH) as f:
            data = json.load(f)
        questions = data['questions']
        return render(request, 'main/test.html', {'questions': questions})

Problem

Without using base.html, the results are displayed correctly in test.html. However, when I extend from base.html, the content within the {% if results %}{% endif %} block doesn't get displayed at all. It seems like the results variable is not recognized when using the base template.

What could be causing this issue, and how can I resolve it?

Initially, I created a standalone template for the test (test.html) without extending any base template. This standalone template correctly displays the results within the {% if results %}{% endif %} block after the form submission.


Solution

  • try put this {% load static %} at the top of the base.html, not inside