Web/Django-python

Django에서 제이쿼리 load와 장고의 extneds, include 를 복합적으로 이용한 페이지 만들기 - 페이지 참조 및 템플릿 확장

제이쿼리에서 다른 html 페이지를 불러오는 데는 .load 라는 메소드를 이용한다.

이는 URL을 지정하여 해당 URL의 내용을 내가 선택한 객체에 넣겠다는 건데, $(#thisdiv).load("URL") 같은 식으로 사용하면 thisdiv의 내용은 URL에서 불러온 내용으로 바뀐다.

즉, 메인 페이지 이동 없이 페이지 안에서 다른 웹 페이지를 불러오게 할 수 있다는 건데, 이는 기존에 사용하던 프레임 방식을 대체한다. 프레임 방식과 다른 차이는 웹 페이지를 독립적으로 불러오는게 아니라 그 페이지의 내용을 가져와 현재 페이지 지정한 객체에 합쳐버리는것 .

해당 URL을 가진 페이지의 html소스를 가져와 현재 페이지에 삽입하는 동작을 한다고 요약할 수 있다.

이제 장고 템플릿에서 지원하는 extends와 include 차례. load와 동작 결과는 같지만 특징은 다르다.

load 처럼 html소스를 가져오는 것은 동일하지만, 제이쿼리처럼 동적으로 동작하지 못하고 페이지가 로드될 때 랜더가 완료된다. 또한, url을 기준으로 가져오는 것이 아니고 파일 디렉토리의 경로를 기준으로 페이지의 코드를 가져온다. 즉, urls.py에 별도에 세팅 없이도 사용할 수 있다는 뜻.

각각의 사용 방법과 그 결과를 비교해보자.

제이쿼리 - .load 메소드

function openPage(pageName){
    $("#viewDiv").css("display","block");
    $("#viewDiv").load("/durumiApp/viewPage/"+pageName);
}

심플하다. html 상에서 클릭시 함수를 호출하는 버튼을 만들어 두고, 해당 함수는 다른 페이지의 내용을 가져와 지정한 div의 내용을 바꾸게 하였다.

view div 자체의 내용이 바뀌는걸 확인할 수 있다.

자바스크립트로 동작하기 때문에 페이지가 이미 로드되었더라도 동적으로 페이지 변경을 할 수 있다.

URL 기반으로 동작하기 때문에 , django에서 이 방식을 사용하기 위해서는 urls.py에 해당하는 페이지들의 URL을 모두 정의해줘야 하고, 그에 맞게 view도 선언하고 지정해줘야 하며 해당하는 웹 페이지들의 templates들도 만들어줘야 한다.

장고 템플릿 - include

<div id ="noteDiv">{% include 'durumiApp/tripNote.html' %}</div>
<div id ="menuDiv">{% include 'durumiApp/hamburgerMenu.html' %}</div>

include의 개념도 어렵지는 않다. 현재 장고 앱의 templates 디렉토리 기준으로 html 파일을 직접 요청하여 그 파일의 내용을 해당 위치에 고정으로 박아버린다.

{% include %} 에 해당하는 내용들이 그 페이지들의 html 소스로 변경되는게 보인다.

load 메소드와는 다르게, 페이지가 로드되고 랜더되는 시점에서 완성되기 때문에 동적으로 페이지를 구성할 수는 없다. 그러나 url과 view에 별도의 선언을 할 필요 없이 페이지의 내용을 바로 불러올 수 있는 장점이 있다.

장고 템플릿 - extends block

이제 제일 혼란스러운 개념인 extends block 인데, 이는 include와 유사하지만 페이지의 역참조가 일어난다는 특성이 있다.

viewbase.html

<html>
    <div id="pageTop">
        this is base view top <br>

        <div id="pageName">
            {% block pageName %}
            {% endblock %}
        </div>
    </div>

    <div id="pageContent">
        {% block pageContent %}
        {% endblock %}
    </div>

    <div id="pageFooter">
        this is base view footer <br>
   </div>
</html>

viewInfo.html

{% extends 'durumiApp/viewBase.html' %}

{% block pageName %}
    viewInfo
{% endblock%}


{% block pageContent %}
    this is view Bases's block contents.
{% endblock %}

viewbase와 viewinfo 두개의 html 페이지가 있을 때, viewbase와 viewinfo 둘 모두에 {% block 블록명 %} 으로 된 영역이 있고 viewinfo에는 {% extend 파일명 %} 으로 특정 파일을 불러오는걸 볼 수 있다.

이렇게 되면 어떤식으로 페이지 참조가 일어나냐면, viewInfo.html 페이지를 장고에서 호출하였을 때 extends 에 의해 viewbase.html 페이지가 불러와지고, viewbase.html에 있는 각각 block 영역에 원래 viewbase의 내용 대신, 해당 페이지를 참조했던 페이지의 블록 컨텐츠가 들어가게 된다.

실제로 브라우저에 로드되는건 viewinfo.html 이지만 안의 내용물은 viewbase.hmtl의 블록안에 viewinfo.html의 블록 컨텐츠가 들어간 셈이라고 생각하면 이해가 편하다. 일종의 역참조가 이뤄지는 셈.

이렇게 복잡한 개념을 어디다가 써먹느냐? 웹 페이지의 경우 상단과 하단은 공통적인 내용을 사용하고, 가운데 컨텐츠 영역만 바꿔서 써야되는 경우가 많다.

그런 경우에 각 페이지에 일일히 include를 하는 대신, 상단과 하단을 가진 베이스 페이지를 하나 만들고 블록 컨텐츠 내용물만 바꿔가면서 페이지를 만들 수 있다. 이 경우 페이지 URL 호출은 각각의 페이지를 호출하게 된다.

include와 용도상 차이를 생각해보면, include는 만들어서 가져는 와야 하지만 그 활용 빈도가 적은 경우에 사용하면 되고, block extends 같은 경우는 공통적으로 포함해야 하는 페이지가 많은 경우에 사용하면 되겠다.

두 방식 모두 프레임 방식을 사용하지 않고 각 페이지간 css 와 속성, 자바스크립트 함수등을 자유롭게 자겨다가 쓸 수 있게끔 만들어진 방식이다. 이렇게 인클루드/익스텐드 한 페이지들은 각각 페이지에 있는 객체, 태그, 함수 등을 모두 자유롭게 사용할 수 있다.