전체 코드는 아래와 같습니다. views.py입니다. step 1부터 step 4까지 주석을 풀면서 실행되는 화면을 확인해주세요.

from django.shortcuts import render
from django.template.loader import render_to_string
from django.http import HttpResponse

def test(request):
    data = [
        {'name': 'leehojun', 'age':10},
        {'name': 'leehojun2', 'age':20}
    ]
    url = 'www.weniv.co.kr'

    # return HttpResponse('hello world') # step 1
    # return HttpResponse('<h1>hello world</h1>') # step 2
    # 결국 render도 HttpResponse를 리턴합니다. :)

    # s = render_to_string('main/test.txt', {'data': data})
    # return HttpResponse(s) # step 3

    # return render(request, 'main/test.html', {"url":url}) # step 4

test.txt 입니다.

{{data}}

{% for i in data %}
<section>
    <h2>{{i.name}}</h2>
    <p>{{i.age}}</p>
<section>
{% endfor %}

test.html 입니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="" method="get">
        <input type="text" id="search-input">
    </form>
    <div class="text"></div>
    <script>
        const form = document.querySelector('form');
        const input = document.querySelector('#search-input');
        const text = document.querySelector('.text');

        const url = '{{ url }}';
        const data = {url};

        input.addEventListener('input', ()=>{
            console.log(input.value)
            text.innerText = `{{url}}/${input.value}`;
        })
    </script>
</body>
</html>

둘 다 화면에서는 같은 형태로 렌더링 되는 것을 볼 수 있습니다. 결국 템플릿 상속도 ‘문자열의 조합’이라는 것입니다.