프로그래밍/파이썬

[Django] 웹 프로그래밍 실습(2) - 템플릿 상속 및 처리 결과

매 석 2022. 11. 15. 23:08
반응형

1. 과거 학습 내용

 

[Django] 웹 프로그래밍 실습(1) - 페이지 연결하기(View, Templates)

1. 장고 기본 지식 장고의 기본 내용은 아래 링크를 참조 [Django 기초] 파이썬 장고 - 개념 정리 및 웹 페이지 만들기 1. 웹 프레임워크란? - 웹 서버를 구현하기 위한 목적으로, 해당 기능들을 모아

maeseok.tistory.com

 

2. 템플릿 상속의 효과

- 쉽게 설명하자면 파이썬의 함수와 비슷하다.

  즉 파이썬에서 반복되는 코드를 함수로 정의하여 적재적소에 사용한다.

  이와 마찬가지로 장고의 templates의 html 파일에서도 반복되는 내용을

  특정 html에 정의하여 함수처럼 사용한다.

 

- 설명을 추가하자면, 함수처럼 정의하는 것이 부모를 정의한 것이고,

  그 코드를 자식에서 사용하려면 부모의 코드를 상속받아야 한다.

  그 때는 아래 코드를 사용하여 상속받는다.

{% extends "상속받을파일이름.html" %}

 

- 이렇게 사용하면 코드의 반복으로 인한 자원 낭비

  코드의 수정이 훨씬 편해지는 효과를 얻을 수 있다.

 

 

 

3. 템플릿 상속의 예시

- Test.html

<!DOCTYPE html>
<html lang="ko" class="no-js">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body class="demo-1">
    <a href="/new">Sign up</a>
    <a href="/logout">Logout</a>
  </body>
</html>

- Test2.html

<!DOCTYPE html>
<html lang="ko" class="no-js">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body class="demo-1">
    <a href="/new">Sign up</a>
    <a href="/login">Login</a>
  </body>
</html>

- 겹치는 내용

<!DOCTYPE html>
<html lang="ko" class="no-js">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body class="demo-1">
    <a href="/new">Sign up</a>
  </body>
</html>

- base.html (템플릿 상속의 부모 역할)

<!DOCTYPE html>
<html lang="ko" class="no-js">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body class="demo-1">
    <a href="/new">Sign up</a>
    {% block content %}
    -- 겹치지 않는 코드는 자식에서 이 부분에 넣어줘야 한다. --
    EX) <a href="/login">Login</a>
    {% endblock %}
  </body>
</html>

 

- Test2.html (템플릿 상속의 자식 역할)

{% extends "base.html" %}
{% block content %}
<a href="/login">Login</a>
{% endblock %}

- 즉 처음에 Test2.html은 10줄로 정의되었지만 현재는 4줄로 정의할 수 있다.

  또한 현재는 2개의 파일이지만 이렇게 겹치는 파일이 100개, 1000개 등 

  크면 클수록 더욱 코드의 재사용 빈도가 커지게 된다.

 

 

 

4. 템플릿 상속의 실제 예시

현재 이러한 웹 페이지를 구성하는 서버의 실제 예시를 보여주겠다.

 

- 장고의 구성은 

프로젝트 : Finance

어플리케이션 : Index, Inquiry, Portfolio로 구성된다.

 

이 중 Index에서 템플릿 상속을 사용한 예시를 보여주겠다.

 

- login.html (템플릿 상속 전)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="주식 포트폴리오와 시세 조회" />
    <meta name="author" content="" />
    <title>FINANCE PORTFOLIO</title>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap"
      rel="stylesheet"
    />
    <link rel="icon" type="image/x-icon" href="../static/assets/bank.svg" />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.0/font/bootstrap-icons.css"
      rel="stylesheet"
    />
    <script
    src="https://code.jquery.com/jquery-3.6.0.js"
    integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
    crossorigin="anonymous"
  ></script>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script
      src="https://kit.fontawesome.com/53a8c415f1.js"
      crossorigin="anonymous"
    ></script>
    <style>
      #main-footer {
        float: bottom;
      }
    </style>
    <script src="../static/js/login.js"></script>
    <link href="../static/css/styles.css" rel="stylesheet" />
    <link rel="stylesheet" href="../static/css/login.css" />
    <script src="../static/js/focus.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container px-lg-5">
        <a class="navbar-brand" href="/">Finance Portfolio</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav my-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/main"
                ><i class="bi bi-house-fill"></i> Home</a
              >
            </li>
            <li class="nav-item" id="inqu">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-search"></i> Inquiry</a
                >
                <div class="dropdown-content" id="inqu-menu">
                  <a href="/inquiry/search">한국주식) 시세 조회</a>
                  <a href="/inquiry/return">한국주식) 수익률 조회</a>
                  <a href="/inquiry/nasdaq">미국주식) 나스닥 조회</a>
                  <a href="/inquiry/nyse">미국주식) 뉴욕 조회</a>
                  <a href="/inquiry/amex">미국주식) 아맥스 조회</a>
                  <a href="/inquiry/etfUS">미국주식) ETF 조회</a>
                  <a href="/inquiry/coin">비트코인) 시세 조회</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="port">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-book"></i> Portfolio</a
                >
                <div class="dropdown-content" id="port-menu">
                  <a href="/portfolio/buy">종목 매수</a>
                  <a href="/portfolio/sell">종목 매도</a>
                  <a href="/portfolio/inquiry">포트폴리오 조회</a>
                  <a href="/portfolio/return">매도 수익</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="init">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-exclamation-triangle"></i> Initialize</a
                >
                <div class="dropdown-content" id="init-menu">
                  <a href="/portfolio/init">포트폴리오 초기화</a>
                </div>
              </div>
            </li>
          </ul>
          <ul class="nav navbar-nav ms-auto">
            {% if session['ID'] %}
            <li>
              <ul class="nav navbar-nav ms-auto">
                <li class="nav-item">
                  <a class="nav-link active" aria-current="page" href="#"
                    ><i class="bi bi-person-fill"></i>{{session['ID']}}</a
                  >
                </li>
              <a class="nav-link active" aria-current="page" href="/logout"
                ><i class="bi bi-box-arrow-left"></i> Logout</a
              >
            </li>
            {% else %}
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/new"
                ><i class="bi bi-person-plus-fill"></i> Sign Up</a
              >
            </li>
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/login"
                ><i class="bi bi-box-arrow-right"></i> Log In</a
              >
            </li>
            {%endif%}
          </ul>
        </div>
      </div>
    </nav>
    <form name="form" action="/login" method="post">
      <div class="wraps">
        <div class="login">
          <h2>Log-in</h2>
          <div class="login_id">
            <h4 class="h4">ID</h4>
            <input
              type="text"
              name="id"
              id="id"
              placeholder="아이디"
              required
            />
          </div>
          <div class="login_pw">
            <h4 class="h4">Password</h4>
            <input
              type="password"
              name="pwd"
              id="pwd"
              placeholder="패스워드"
              required
            />
          </div>
          <!--<div class="login_etc">
          <<div class="checkbox">
            <input type="checkbox" name="" id="" /> Remember Me?
          </div>
          <div class="forgot_pw">
            <a href="">Forgot Password?</a>
          </div>
        </div>-->
          <div class="submit">
            <input type="submit" id="submit" value="submit" />
          </div>
        </div>
      </div>
    </form>
	{%if messages %}
    <script type="text/javascript">
      alert("{{messages.tags}}");
    </script>
    {%endif%}
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
  </body>
</html>

 

- new.html (템플릿 상속 전)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="주식 포트폴리오와 시세 조회" />
    <meta name="author" content="" />
    <title>FINANCE PORTFOLIO</title>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap"
      rel="stylesheet"
    />
    <link rel="icon" type="image/x-icon" href="../static/assets/bank.svg" />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.0/font/bootstrap-icons.css"
      rel="stylesheet"
    />
    <script
      src="https://code.jquery.com/jquery-3.6.0.js"
      integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
      crossorigin="anonymous"
    ></script>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script
      src="https://kit.fontawesome.com/53a8c415f1.js"
      crossorigin="anonymous"
    ></script>
    <style>
      #main-footer {
        float: bottom;
      }
    </style>
    <script src="../static/js/login.js"></script>
    <link href="../static/css/styles.css" rel="stylesheet" />
    <link rel="stylesheet" href="../static/css/login.css" />
    <script src="../static/js/focus.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container px-lg-5">
        <a class="navbar-brand" href="/">Finance Portfolio</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav my-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/main"
                ><i class="bi bi-house-fill"></i> Home</a
              >
            </li>
            <li class="nav-item" id="inqu">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-search"></i> Inquiry</a
                >
                <div class="dropdown-content" id="inqu-menu">
                  <a href="/inquiry/search">한국주식) 시세 조회</a>
                  <a href="/inquiry/return">한국주식) 수익률 조회</a>
                  <a href="/inquiry/nasdaq">미국주식) 나스닥 조회</a>
                  <a href="/inquiry/nyse">미국주식) 뉴욕 조회</a>
                  <a href="/inquiry/amex">미국주식) 아맥스 조회</a>
                  <a href="/inquiry/etfUS">미국주식) ETF 조회</a>
                  <a href="/inquiry/coin">비트코인) 시세 조회</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="port">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-book"></i> Portfolio</a
                >
                <div class="dropdown-content" id="port-menu">
                  <a href="/portfolio/buy">종목 매수</a>
                  <a href="/portfolio/sell">종목 매도</a>
                  <a href="/portfolio/inquiry">포트폴리오 조회</a>
                  <a href="/portfolio/return">매도 수익</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="init">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-exclamation-triangle"></i> Initialize</a
                >
                <div class="dropdown-content" id="init-menu">
                  <a href="/portfolio/init">포트폴리오 초기화</a>
                </div>
              </div>
            </li>
          </ul>
          <ul class="nav navbar-nav ms-auto">
            {% if session['ID'] %}
            <li>
              <ul class="nav navbar-nav ms-auto">
                <li class="nav-item">
                  <a class="nav-link active" aria-current="page" href="#"
                    ><i class="bi bi-person-fill"></i>{{session['ID']}}</a
                  >
                </li>
              <a class="nav-link active" aria-current="page" href="/logout"
                ><i class="bi bi-box-arrow-left"></i> Logout</a
              >
            </li>
            {% else %}
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/new"
                ><i class="bi bi-person-plus-fill"></i> Sign Up</a
              >
            </li>
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/login"
                ><i class="bi bi-box-arrow-right"></i> Log In</a
              >
            </li>
            {%endif%}
          </ul>
        </div>
      </div>
    </nav>
    <form name="form" action="/new" method="post">
      <div class="wraps">
        <div class="login">
          <h2>회원가입</h2>
          <div class="login_id">
            <h4 class="h4">ID</h4>
            <input
              type="text"
              name="id"
              id="id"
              placeholder="아이디"
              required
            />
          </div>
          <div class="login_pw">
            <h4 class="h4">Password</h4>
            <input
              type="password"
              name="pwd"
              id="pwd"
              placeholder="패스워드"
              class="pw"
              required
            />
          </div>
          <div class="login_pw">
            <h4 class="h4">Password check</h4>
            <div>
              <input
                type="password"
                name="pwd2"
                class="pw"
                id="pwd2"
                placeholder="패스워드 확인"
                required
              />
              <span id="alert-success" style="display: none"
                >비밀번호가 일치합니다.</span
              >
              <span
                id="alert-danger"
                style="display: none; color: #d92742; font-weight: bold"
                >비밀번호가 일치하지 않습니다.</span
              >
            </div>
            <div class="login_id">
              <h4 class="h4">닉네임</h4>
              <input
                type="text"
                name="nick"
                id="nick"
                placeholder="닉네임"
                required
              />
            </div>
          </div>
          <script>
            $(".pw").focusout(function () {
              const pwd1 = $("#pwd").val();
              const pwd2 = $("#pwd2").val();

              if (pwd1 != "" && pwd2 == "") {
                null;
              } else if (pwd1 != "" || pwd2 != "") {
                if (pwd1 == pwd2) {
                  $("#alert-success").css("display", "inline-block");
                  $("#alert-danger").css("display", "none");
                } else {
                  $("#alert-success").css("display", "none");
                  $("#alert-danger").css("display", "inline-block");
                  pwd1.focus();
                  pwd2.focus();
                  return false;
                }
              }
            });
          </script>
          <!--<div class="login_etc">
          <<div class="checkbox">
            <input type="checkbox" name="" id="" /> Remember Me?
          </div>
          <div class="forgot_pw">
            <a href="">Forgot Password?</a>
          </div>
        </div>-->
          <div class="submit">
            <input type="submit" id="submit" value="가입" />
          </div>
        </div>
      </div>
    </form>
    {%if messages %}
    <script type="text/javascript">
      alert("{{messages.tags}}");
    </script>
    {%endif%}
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
  </body>
</html>

- base.html (템플릿 상속의 부모 역할)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="주식 포트폴리오와 시세 조회" />
    <meta name="author" content="" />
    <title>FINANCE PORTFOLIO</title>
    <link rel="icon" type="image/x-icon" href="../static/assets/bank.svg" />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.0/font/bootstrap-icons.css"
      rel="stylesheet"
    />
    <script
      src="https://code.jquery.com/jquery-3.6.0.js"
      integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
      crossorigin="anonymous"
    ></script>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap"
      rel="stylesheet"/>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script
      src="https://kit.fontawesome.com/53a8c415f1.js"
      crossorigin="anonymous"
    ></script>
    <style>
      #main-footer {
        float: bottom;
      }
    </style>
    <script src="../static/js/login.js"></script>
    <link href="../static/css/styles.css" rel="stylesheet" />
    <link rel="stylesheet" href="../static/css/login.css" />
    <script src="../static/js/focus.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container px-lg-5">
        <a class="navbar-brand" href="/">Finance Portfolio</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav my-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/main"
                ><i class="bi bi-house-fill"></i> Home</a
              >
            </li>
            <li class="nav-item" id="inqu">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-search"></i> Inquiry</a
                >
                <div class="dropdown-content" id="inqu-menu">
                  <a href="/Inquiry/search">한국주식) 시세 조회</a>
                  <a href="/Inquiry/return">한국주식) 수익률 조회</a>
                  <a href="/Inquiry/nasdaq">미국주식) 나스닥 조회</a>
                  <a href="/Inquiry/nyse">미국주식) 뉴욕 조회</a>
                  <a href="/Inquiry/amex">미국주식) 아맥스 조회</a>
                  <a href="/Inquiry/etfUS">미국주식) ETF 조회</a>
                  <a href="/Inquiry/coin">비트코인) 시세 조회</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="port">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-book"></i> Portfolio</a
                >
                <div class="dropdown-content" id="port-menu">
                  <a href="/Portfolio/buy">종목 매수</a>
                  <a href="/Portfolio/sell">종목 매도</a>
                  <a href="/Portfolio/inquiry">포트폴리오 조회</a>
                  <a href="/Portfolio/return">매도 수익</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="init">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-exclamation-triangle"></i> Initialize</a
                >
                <div class="dropdown-content" id="init-menu">
                  <a href="/Portfolio/init">포트폴리오 초기화</a>
                </div>
              </div>
            </li>
          </ul>
          <ul class="nav navbar-nav ms-auto">
            {% if request.session.user %}
            <li>
              <ul class="nav navbar-nav ms-auto">
                <li class="nav-item">
                  <a class="nav-link active" aria-current="page" href="#"
                    ><i class="bi bi-person-fill"></i>{{request.session.user}}</a
                  >
                </li>
              <a class="nav-link active" aria-current="page" href="/logout"
                ><i class="bi bi-box-arrow-left"></i> Logout</a
              >
            </li>
            {% else %}
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/new"
                ><i class="bi bi-person-plus-fill"></i> Sign Up</a
              >
            </li>
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/login"
                ><i class="bi bi-box-arrow-right"></i> Log In</a
              >
            </li>
            {%endif%}
          </ul>
        </div>
      </div>
    </nav>
    {% block content %} 
    {% endblock %}
</body>
</html>

- login.html (템플릿 상속 후)

{% extends 'base.html' %}
{% block content %}
<form name="form" action="/login" method="post">
  <div class="wraps">
    <div class="login">
      <h2>Log-in</h2>
      <div class="login_id">
        <h4 class="h4">ID</h4>
        <input
          type="text"
          name="id"
          id="id"
          placeholder="아이디"
          required
        />
      </div>
      <div class="login_pw">
        <h4 class="h4">Password</h4>
        <input
          type="password"
          name="pwd"
          id="pwd"
          placeholder="패스워드"
          required
        />
      </div>
      <!--<div class="login_etc">
      <<div class="checkbox">
        <input type="checkbox" name="" id="" /> Remember Me?
      </div>
      <div class="forgot_pw">
        <a href="">Forgot Password?</a>
      </div>
    </div>-->
      <div class="submit">
        <input type="submit" id="submit" value="submit" />
      </div>
    </div>
  </div>
</form>
{%if messages %}
<script type="text/javascript">
  alert("{{messages.tags}}");
</script>
{%endif%}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
{% endblock %}

- new.html (템플릿 상속 후)

{% extends 'base.html' %}
{% block content %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="주식 포트폴리오와 시세 조회" />
    <meta name="author" content="" />
    <title>FINANCE PORTFOLIO</title>
    <link rel="icon" type="image/x-icon" href="../static/assets/bank.svg" />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.0/font/bootstrap-icons.css"
      rel="stylesheet"
    />
    <script
      src="https://code.jquery.com/jquery-3.6.0.js"
      integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
      crossorigin="anonymous"
    ></script>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap"
      rel="stylesheet"/>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script
      src="https://kit.fontawesome.com/53a8c415f1.js"
      crossorigin="anonymous"
    ></script>
    <style>
      #main-footer {
        float: bottom;
      }
    </style>
    <script src="../static/js/login.js"></script>
    <link href="../static/css/styles.css" rel="stylesheet" />
    <link rel="stylesheet" href="../static/css/login.css" />
    <script src="../static/js/focus.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container px-lg-5">
        <a class="navbar-brand" href="/">Finance Portfolio</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav my-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/main"
                ><i class="bi bi-house-fill"></i> Home</a
              >
            </li>
            <li class="nav-item" id="inqu">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-search"></i> Inquiry</a
                >
                <div class="dropdown-content" id="inqu-menu">
                  <a href="/Inquiry/search">한국주식) 시세 조회</a>
                  <a href="/Inquiry/return">한국주식) 수익률 조회</a>
                  <a href="/Inquiry/nasdaq">미국주식) 나스닥 조회</a>
                  <a href="/Inquiry/nyse">미국주식) 뉴욕 조회</a>
                  <a href="/Inquiry/amex">미국주식) 아맥스 조회</a>
                  <a href="/Inquiry/etfUS">미국주식) ETF 조회</a>
                  <a href="/Inquiry/coin">비트코인) 시세 조회</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="port">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-book"></i> Portfolio</a
                >
                <div class="dropdown-content" id="port-menu">
                  <a href="/Portfolio/buy">종목 매수</a>
                  <a href="/Portfolio/sell">종목 매도</a>
                  <a href="/Portfolio/inquiry">포트폴리오 조회</a>
                  <a href="/Portfolio/return">매도 수익</a>
                </div>
              </div>
            </li>
            <li class="nav-item" id="init">
              <div class="dropdown">
                <a class="nav-link" href="#"
                  ><i class="bi bi-exclamation-triangle"></i> Initialize</a
                >
                <div class="dropdown-content" id="init-menu">
                  <a href="/Portfolio/init">포트폴리오 초기화</a>
                </div>
              </div>
            </li>
          </ul>
          <ul class="nav navbar-nav ms-auto">
            {% if session['ID'] %}
            <li>
              <ul class="nav navbar-nav ms-auto">
                <li class="nav-item">
                  <a class="nav-link active" aria-current="page" href="#"
                    ><i class="bi bi-person-fill"></i>{{session['ID']}}</a
                  >
                </li>
              <a class="nav-link active" aria-current="page" href="/logout"
                ><i class="bi bi-box-arrow-left"></i> Logout</a
              >
            </li>
            {% else %}
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/new"
                ><i class="bi bi-person-plus-fill"></i> Sign Up</a
              >
            </li>
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/login"
                ><i class="bi bi-box-arrow-right"></i> Log In</a
              >
            </li>
            {%endif%}
          </ul>
        </div>
      </div>
    </nav>
    <form name="form" action="/new" method="post">
      <div class="wraps">
        <div class="login">
          <h2>회원가입</h2>
          <div class="login_id">
            <h4 class="h4">ID</h4>
            <input
              type="text"
              name="id"
              id="id"
              placeholder="아이디"
              required
            />
          </div>
          <div class="login_pw">
            <h4 class="h4">Password</h4>
            <input
              type="password"
              name="pwd"
              id="pwd"
              placeholder="패스워드"
              class="pw"
              required
            />
          </div>
          <div class="login_pw">
            <h4 class="h4">Password check</h4>
            <div>
              <input
                type="password"
                name="pwd2"
                class="pw"
                id="pwd2"
                placeholder="패스워드 확인"
                required
              />
              <span id="alert-success" style="display: none"
                >비밀번호가 일치합니다.</span
              >
              <span
                id="alert-danger"
                style="display: none; color: #d92742; font-weight: bold"
                >비밀번호가 일치하지 않습니다.</span
              >
            </div>
            <div class="login_id">
              <h4 class="h4">닉네임</h4>
              <input
                type="text"
                name="nick"
                id="nick"
                placeholder="닉네임"
                required
              />
            </div>
          </div>
          <script>
            $(".pw").focusout(function () {
              const pwd1 = $("#pwd").val();
              const pwd2 = $("#pwd2").val();

              if (pwd1 != "" && pwd2 == "") {
                null;
              } else if (pwd1 != "" || pwd2 != "") {
                if (pwd1 == pwd2) {
                  $("#alert-success").css("display", "inline-block");
                  $("#alert-danger").css("display", "none");
                } else {
                  $("#alert-success").css("display", "none");
                  $("#alert-danger").css("display", "inline-block");
                  pwd1.focus();
                  pwd2.focus();
                  return false;
                }
              }
            });
          </script>
          <!--<div class="login_etc">
          <<div class="checkbox">
            <input type="checkbox" name="" id="" /> Remember Me?
          </div>
          <div class="forgot_pw">
            <a href="">Forgot Password?</a>
          </div>
        </div>-->
          <div class="submit">
            <input type="submit" id="submit" value="가입" />
          </div>
        </div>
      </div>
    </form>
    {%if messages %}
    <script type="text/javascript">
      alert("{{messages.tags}}");
    </script>
    {%endif%} 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
{% endblock %}

 

 

- login.html의 경우 상속 전은 177줄 상속 후는 47줄로 무려 130줄이나 되는 코드를 줄일 수 있었다.

- 위의 예시에도 알 수 있듯이 {% block %} 태그는 여러 번 사용할 수 있다.