Django

Django Extends 이용해서 Navigation Bar 구현

- Django 블로그 만들기

Jan. 11, 2023, 11:19 p.m.

안녕하세요?

지난 포스트에서는 블로그 글을 조회할 수 있도록 해보았는데요,

포스트 글을 조회하는 post.html 페이지에서도 상단 네비게이션 바의 메뉴 같은 부분은 모두 구성이 동일하나,

각 html 파일마다 해당 부분을 동일하게 복붙해놓은 형태로 코드가 낭비되고 있습니다.

또한, 페이지가 늘어날 수록 관리하기 번거로워 지는 치명적인 단점도 있을 것입니다.

 

 

 

 

그래서 오늘은 네비게이션 바와 같은 모든 페이지가 동일하게 구성되는 부분은

한 부분에서만 컨트롤할 수 있도록 소스코드를 변경해보려고 합니다!

이 때, 필요한 것이 django extends 기능 입니다.

 

Django Extends 란?

태그를 이용하여 특정 부위에 다른 템플릿을 가져다가 쓰는 형식으로, 

아래의 간단한 예시를 보면,

<html>
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
  </head>
 <body>

    {% block content %}

    {% endblock %} 
      
  </body>
</html>

 {% block content %}...{% endblock %} 에 해당하는 부분 사이에, 다른 html 템플릿을 불러오게 됩니다.

이를 저희가 개발하던 소스코드에 적용해보도록 하겠습니다.

 

 

index.html 의 main content 수정

index.html 파일의 <!-- Main Content-->부분을 찾아서 아래와 같이 수정합니다.

<!-- index.html 
중략..-->

<!-- Main Content-->
{% block content %}
{% endblock %}
<!-- Footer-->

 

그리고 기존에 있던 내용은 home.html 파일을 새로 생성하여 붙여넣어 줍니다.

<!-- home.html-->

{% extends "index.html" %}
{% block content %}
<!-- Main Content-->
        <div class="container px-4 px-lg-5">
            <div class="row gx-4 gx-lg-5 justify-content-center">
                <div class="col-md-10 col-lg-8 col-xl-7">
                    {% for object in objects %}
                        <div class="preview">
                            <blog class="media content-section customhover" style="height: 95%;">
                                <div class="media-body">
                                    <a href="/post/{{object.slug}}">
                                        <!--<img class="img-fluid" src="/">-->
                                        <h1 class="post-title" >{{ object.title }} </h1>
                                        <h3 class="post-subtitle">{{ object.subtitle }}</h3>
                                    </a>
                                    <p class="post-meta">
                                            Posted by
                                            <a href="/post/{{object.slug}}">Sanlab</a>
                                            on {{ object.published }}
                                    </p>
                                   
                                </div>
                            </blog>
                        </div>
                        <!-- Divider-->
                        <hr class="my-4" />
                    {% endfor %}
                    <!-- Post preview-->
                    <!-- Pager-->
                    <div class="d-flex justify-content-end mb-4"><a class="btn btn-primary text-uppercase" href="#!">Older Posts →</a></div>
                </div>
            </div>
        </div>
{% endblock content %}

 

views.py 파일 수정

위에서 수정을 해주면서 이제 index.html 파일은 모든 파일에 공통적인 네비게이션 바와 footer 를 보여주는 화면이 되었고,

메인 화면은 home.html 이 대체하게 되었습니다.

이를 views.py 파일에도 적용해줘야 합니다.

#blog/views.py

def index(request):
    matching_article = Article.objects.all()

    return render(request=request,
                  template_name='home.html',
                  context={"objects": matching_article}
                  )

 

여기까지 수정 후 저장하고, 서버를 올려서 메인화면을 확인해보면

아래와 같이 기존 화면과 동일하게 잘 뜨면 변경 성공입니다.

 

 

post.html 수정

post.html 파일은 아직 네비게이션 바 부분이 하드코딩 되어있으니,

index.html 이 수정된 것에 맞춰서 아래와 같이 수정해줍니다.

{% extends "index.html" %}

{% block content %}
    <!-- Post Content-->
    <article class="mb-4">
        <div class="container px-4 px-lg-5">
            <div class="row gx-4 gx-lg-5 justify-content-center">
                <div class="col-md-10 col-lg-8 col-xl-7">
                    {{article.content}}
                </div>
            </div>
        </div>
    </article>
{% endblock content %}        

 

수정 후 저장하여, 포스트를 클릭했을 때 아래와 같이 기존과 동일하게 잘 뜨면 성공입니다.

 

앗, 그런데 내용이 잘 뜬것인가 싶은데

보니깐 게시물의 title이나 subtitle은 정상적으로 안바뀌고 있는 것이 보입니다.

이는 저희가 해당 부분이 포함되는 header 부분은 모두 index.html 에 포함시켜놨기 때문인데요,

이건 어떻게 해야할 까요?

 

Block 을 이용하여 동적으로 내용 관리하기

저희가 이전에는 main content 부분에만 block 을 사용하였지만,

사실 이는 다른 부분에도(<head> 부분까지도!) 사용이 가능합니다.

그러면 이를 이용하여 본격적으로 수정해보겠습니다.

 

index.html 파일의 title 부분을 아래와 같이 바꾸고

<!-- index.html -->


<title>Clean Blog - {% block title %}{% endblock title %}</title>

 

<!--Page Header--> 부분을 찾아서 아래와 같이 수정합니다.

<!-- index.html-->

<!-- Page Header-->
        <header class="masthead" style="background-image: url('assets/img/home-bg.jpg')">
            <div class="container position-relative px-4 px-lg-5">
                <div class="row gx-4 gx-lg-5 justify-content-center">
                    <div class="col-md-10 col-lg-8 col-xl-7">
                        <div class="site-heading">
                            <h1>{% block title2 %}Test Blog{% endblock title2 %}</h1>
                            <span class="subheading">{% block subtitle %}Python, Django, Java, Android, Swift, Data Science..{% endblock subtitle %}</span>
                            <span class="meta"> {% block pub %} {% endblock pub %} </span>
                        </div>
                    </div>
                </div>
            </div>
        </header>
        <!-- Main Content-->

이렇게 하면 각 block 사이의 내용은 다른 페이지에서 지정을 해줄 수 있고, 그 사이에 들어가있는 값은 현재 페이지에서 조회되는 값입니다.

즉, <h1>{% block title2 %}Test Blog{% endblock title2 %}</h1> 의 코드는

이 페이지에서는 'Test Blog'로 보여주고, 다른 페이지 조회 시 title2 라는 태그를 찾아서 그 값을 조회한다는 뜻입니다.

 

이제, post.html 파일을 아래와 같이 수정합니다.

{% extends "index.html" %}
{% block title %} {{ article.title }} {% endblock title %}
{% block title2 %} {{ article.title }} {% endblock title2 %}
{% block subtitle %} {{ article.subtitle }} {% endblock subtitle %}
{% block pub %}Posted by Sanlab {{article.published}} {% endblock pub %}

{% block content %}
    <!-- Post Content-->
    <article class="mb-4">
        <div class="container px-4 px-lg-5">
            <div class="row gx-4 gx-lg-5 justify-content-center">
                <div class="col-md-10 col-lg-8 col-xl-7">
                    {{article.content}}
                </div>
            </div>
        </div>
    </article>
{% endblock content %}        

이는 각 태그에 해당하는 값들을 지정해주는 것입니다.

 

여기까지 저장하고, 다시 포스트를 클릭하면 아래와 같이 title, subtitle 등도 정상적으로 조회되는 것이 보입니다.

 

이제 블로그의 틀이 거의 완성되었습니다.

그런데 현재까지는 텍스트밖에 블로그에 입력이 안되는 상황입니다.

텍스트만으로 블로그 글을 작성할 수 없겠죠?

그러면 다음 포스트에서는 텍스트 뿐 아니라 이미지, 코드 등을 입력할 수 있는 에디터 사용하는 방법을 알아보겠습니다.

Reference


Project

Comments


Related Posts