본문 바로가기
Language/파이썬

장고(django) 프로젝트 첫 페이지, 템플릿 상속 - 파이썬 장고를 활용한 쉽고 빠른 웹 개발 프로그래밍

by javapp 자바앱 2022. 1. 11.
728x90

 

URL 설정

mysite/urls.py

...
from mysite.views import HomeView  # 홈페이지

urlpatterns = [
	...
    # 홈페이지
    path('',HomeView.as_view(), name='home'), # 루트 URL , 패턴명 = 'home'
]

 

 

View 설정

단순히 템플릿만 보여주는 로직

mysite/views.py

# 홈페이지

from django.views.generic import TemplateView

class HomeView(TemplateView):
    template_name = 'home.html'

TemplateView 제네릭 뷰 상속

 

 

settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # add home page html
        'DIRS': [os.path.join(BASE_DIR,'templates')],

		...
    }
]

템플릿 dir 위치 설정

 


 

템플릿 상속 기능 적용

첫 페이지 화면

네비게이션 부분 footer 부분을 상위 파일(base.html)로 두고 상속 기능을 적용시켜

home.html을 base.html 파일을 상속받는 방식으로 적용

 

 

home.html 전체 코드

더보기
더보기
더보기
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

    <title>{% block title %} JJango Web Programming {% endblock %}</title>

    {% block extra-style %}{% endblock %}
</head>
<body style="padding-top:90px">

<!--    home html -->
    <nav class="navbar navbar-expand-lg bg-primary navbar-fixed-top navbar-dark" >
        <span class="navbar-brand mx-5 mb-0 font-weight-bold font-italic">JJango - Python Web Programming</span>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent">
            <span class="navbar-toggler-icon"></span>
        </button>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="nav navbar-nav">
            <li class="nav-item mx-1 btn btn-primary">
                <a href="{% url 'home' %}"  class="nav-link btn-primary" >Home </a>
            </li>

            <li class="nav-item mx-1 btn btn-primary">
                <a href="{% url 'blog:index' %}" class="nav-link btn-primary" >Blog </a>
            </li>
<!--            <li class="nav-item mx-1 btn btn-primary">-->
<!--                <a href="% url 'Photo:index' %}" class="nav-link" text-white>Photo </a>-->
<!--            </li>-->

            <li class="nav-item dropdown mx-1 btn btn-primary">
              <a href="#" class="nav-link dropdown-toggle btn-primary" data-toggle="dropdown" role="button" aria-expanded="false">Util <span class="caret"></span></a>
                <ul class="dropdown-menu" role="menu">
                    <li><a href="{% url 'admin:index' %}" class="dropdown-item">Admin</a></li>
                    <li class="divider"></li>
                    <li><a href="{% url 'blog:post_archive' %}" class="dropdown-item">Archive</a></li>
                    <li><a href="" class="dropdown-item">Search</a></li>
                </ul>
<!--                <a href="#" class="nav-link dropdown-toggle btn-primary" data-toggle="dropdown" role="button" aria-expanded="false">Util <span class="caret"></span></a>-->
<!--                <div class="dropdown-menu">-->
<!--                    <a href="{% url 'admin:index' %}" class="dropdown-item">Admin</a>-->
<!--                    <div class="divider"></div>-->
<!--                    <a href="{% url 'blog:post_archive' %}" class="dropdown-item">Archive</a>-->
<!--                    <a href="" class="dropdown-item">Search</a>-->
<!--                </div>-->
            </li>
          </ul>

          <form class="form-inline my-2" action="" method="post" role="search">
              {% csrf_token %}
                <input class="form-control mr-sm-2" type="search" placeholder="global search" name="search_word">
          </form>
        </div><!-- /.navbar-collapse -->

    </nav>

    <div class="container">
        {% block content %}{% endblock %}
    </div>

<!-- 하위 html 파일에서 변경하거나 추가할 가능성이 있는 부분에는  % block % 태그를 추가 -->
    {% block footer %}{% endblock %}

    {% block extra-script %}{% endblock %}
</body>
</html>

 

home.html

더보기
더보기
더보기
{% extends 'base.html' %} <!--  태그 문장은 항상 첫 줄에 작성 -->

<!-- 파일 static 로딩하기 위해-->
{% load static %}

<!-- title 재정의 (오버라이드)-->
{% block title %} home.html {% endblock %}

<!--css-->
{% block extra-style %}
<style type="text/css">
    .home-image{
    background-image: url("{% static 'img/back.jpg' %}");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 100%;
    height:500px;
    border-top: 10px solid #CCC;
    border-bottom: 10px solid #CCC;
    padding: 20px 0 0 20px;
}
.title{
    color: #c80;
    font-weight: bold;
}
.powered{
    position: relative;
    top: 77%;
    color: #cc0;
    font-style: italic;
}
</style>
{% endblock %}

{% block content %}
    <div class="home-image">
        <h2 class="title">JJanggo - Python Web Programming</h2>
        <h4 class="powered"><i class="fas fa-arrow-circle-right"></i> powered by jjango and bootstrap</h4>
    </div>

    <hr style="margin:10px 0;">

    <div class="row text-center">
        <div class="col-sm-6">
            <h3>Bookmark App</h3>
            <p>Bookmark is a 통합 자원 식별자
            You can store your own bookmarks by Bookmark application.
        </div>
        <div class="col-sm-6">
            <h3>Blog App</h3>
            <p>This application makes it possible to log daily events or write</p>
        </div>
    </div>
{% endblock content %}

{% block footer %}
<footer class="navbar-fixed-bottom bg-info">
    <div class="text-white font-italic text-right mr-5">Copyright &copy; 2021 JJango Book</div>
</footer>
{% endblock %}

 

코멘트

  •  
{% extends 'base.html' %} <!--  태그 문장은 항상 첫 줄에 작성 -->

base.html 템플릿 파일을 상속 받는다.

 

 

  •  
<!-- 파일 static 로딩하기 위해-->
{% load static %}

 

  •  
<title>{% block title %} JJango Web Programming {% endblock %}</title>

각 페이지마다 달라지는 부분은 {% block %} 태그를 사용

하위 html 에서 오버라이딩을 하면 값이 변경된다.

 

 

home.html 에서

<!-- title 재정의 (오버라이드)-->
{% block title %} home.html {% endblock %}
 JJango Web Programming --> home.html

 

  •  
{% block extra-style %}{% endblock %}

css  코드 삽입 부분

이걸 따로 정적 파일로 두는 방법을 찾아야 될듯

 

 

  •  
<form class="form-inline my-2" action="" method="post" role="search">
    {% csrf_token %}
      <input class="form-control mr-sm-2" type="search" placeholder="global search" name="search_word">
</form>

 

 

 

  •  

base.html

<div class="container">
    {% block content %}{% endblock %}
</div>

 

 

 

  •  
<!-- 하위 html 파일에서 변경하거나 추가할 가능성이 있는 부분에는  % block % 태그를 추가 -->
    {% block footer %}{% endblock %}

 

 

 

 


 

 

 

 

Bookmark 앱과 Blog 앱 또한 base.html 을 상속하여 템플릿 적용해보기

 

bookmark_list.html

{% extends "base.html" %}

<!--어느 템플릿 인지 디버깅시 인지-->
{% block title %}bookmark_list.html{% endblock %}

{% block content %}
    <h1>Bookmark List</h1>
    <br>

    <ul>
        {% for bookmark in object_list %}
            <li> <a href="{% url 'bookmark:detail' bookmark.id %}">{{bookmark}}</a> </li>
        {% endfor %}
    </ul>
{% endblock %}

 

bookmark_detail.html

{% extends "base.html" %}

{% block title %}bookmark_detail.html{% endblock %}

{% block content %}
    <h1>{object.title}</h1>\

    <ul>
          <li>URL: <a href="{{object.url}}">{{object.url}}</a></li>
    </ul>
{% endblock %}

 

post_all.html

{% extends "base.html" %}

{% block title %}post_all.html{% endblock %}

{% block content %}
    <h1>Blog List</h1>
    <br>
<!--    View 에서 context_object_name = 'posts' 라고 정의 했다., object_list 로 호출 가능 -->
    {% for post in posts%}
        <h3> <a href="{{post.get_absolute_url }}">{{ post.title }} </a></h3>
        {{ post.modify_dt | date:"N d, Y"}}
        <p>{{post.description}}</p>
    {% endfor %}

    <br>

    <div>
        <span>
<!--        page_obj 는 장고의 Page 객체가 들어 있는 컨텍스트 변수 : 현재 페이지를 기준으로 이전 페이지가 있는지 확인-->

            {% if page_obj.has_previous %}
<!--            쿼리 스트링, previous_page_number : 이전 페이지 번호 -->
                <a href="?page={{page_obj.previous_page_number}}">PreviousPage</a>
            {% endif %}

            Page {{ page_obj.number}} of {{page_obj.paginator.num_pages}}

            {% if page_obj.has_next %}
<!--            ?page=5, next_page_number : 다음 페이지 번호-->
                <a href="?page={{page_obj.next_page_number}}">NextPage</a>
            {% endif %}
        </span>
    </div>
{% endblock %}

 

post_detail.html

{% extends "base.html" %}

{% block title %}post_all.html{% endblock %}

{% block content %}
  <div>
    <h2>{{object.title}}</h2>
    <p>
        {% if object.get_previous %}
        <!-- get_previous.get_absolute_url 함수를 지징하는 URL 패턴을 반환한다. -->
        <!-- &laquo; 는 HTML 특수문자 '<<<' 를 의미한다.  -->
        <a href="{object.get_previous.get_absolute_url}" title="View previous post">&laquo;- {{object.get_previous}}</a>
        {% endif %}

        {% if object.get_next %}
        <!-- get_next.get_absolute_url 함수를 지칭하는 URL 패넡을 반환한다. -->
        <!-- &raquo; 는 HTML 특수문자 '>>>'를 의미한다.  -->
        | <a href="{{object.get_next.get_absolute_url}}" title="View next post">{{object.get_next}} -&raquo;</a>
        {% endif %}

    </p>
      <!-- 장고 date 템플릿 필터에 설명 참고 -->
      <p>{{object.modify_dt|date:"j F Y"}}</p>

      <br>
  </div>
  <div>
      {{object.content | linebreaks}} <!-- linebreaks : \n -->
  </div>
{% endblock %}

댓글