본문 바로가기
WebFramework/Python Django

[Python Django] 5. Django의 기본 파일 살펴보기 - urls.py(2)

by Rosmary 2021. 7. 24.
728x90
반응형

 

 

 

 

 

지난 포스팅에서는 Django 웹 사이트의 호출된 URL 주소와 연결된 페이지를 정의하는 views.py 파일의 기본적인 부분에 대해 알아보았다. 필자가 간단하게 만든 html 페이지가 특정 URL 주소(/test/)와 맵핑되어 화면에 출력되는 내용까지 확인해보았다.

 

이제, urls.py와 views.py 파일을 사용하면 URL과 특정 페이지의 매핑을 진행하는 것은 어렵지 않을 듯 하다. 따라서 필자는 지금까지 진행했던 실습내용을 싹 다 밀어버리고, python.org의 url에 맞춰, Django 웹 사이트를 구축해보려고 한다. 

 

python.org의 매인 페이지의 주소는 단순하게 python.org로 표시된다.

 

그리고 아래의 About, Download를 클릭하면, 이 매인 페이지 URL 뒤에 /about 또는 /downloads의 주소가 추가된다.

 

이들 페이지의 하부 영역 역시, 여러 페이지로 나뉘어진다. 예를 들어, Python.org/about URL의 경우, 하위에 /apps, /quotes, /gettingstarted, /help 등으로 세부 주소가 정의되어 있다.

 

 

 

정리하자면, urls.py와 views.py 파일을 이용하여 다음과 같은 구조로 웹 사이트의 URL과 페이지를 맵핑해보려 한다

(너무 많은 듯 해서 일부만 진행해보려 한다).

 

*  매인페이지: https://172.30.1.50:8080/                    ->   index.html

*  About 페이지: https://172.30.1.50:8080/about         ->   about_index.html

   -  apps 페이지: https://172.30.1.50:8080/about/apps       -> about_apps.html

   -  quotes 페이지: https://172.30.1.50:8080/about/quotes      -> about_quotes.html

   -  help 페이지: https://172.30.1.50:8080/about/help        ->  about_help.html

*  Downloads 페이지: https://172.30.1.50:8080/downloads       -> downloads_index.html

   -  windows 페이지: https://172.30.1.50:8080/downloads/windows      -> downloads_windows.html

   -  mac-os 페이지 : https://172.30.1.50:8080/downloads/mac-osx       -> downloads_macos.html

   -  기타 페이지:  https://172.30.1.50:8080/downloads/other               -> downloads_other.html

 

 

위의 구조상으로 볼 때, Django의 어플리케이션은 크게 3가지가 필요하다. main, about 그리고 downloads. 따라서 이 3가지 어플리케이션을 django-admin 명령어로 생성해준다.

 

downloads에 오타가 있다. 수정하긴 했는데 스크린샷 교체는 조금 귀찮다... 

 

명령어로 어플리케이션을 생성하고 난 뒤, 이들 어플리케이션을 웹 사이트 기본 설정 파일인 settings.py의 INSTALLED_APPS에 등록해준다. 

 

이제 위의 URL 주소 구성에 맞게 기본 urls.py 파일을 수정해야 한다. 지금까지 알아보았던 내용으로만 urls.py 파일을 작성하면, 아래와 같이 나타낼 수 있다.

 

 

위와 같이 작성하다보면 문득 이런 생각이 든다.

 

"지금이야 어플리케이션이 3개 뿐이니 이렇게 작성을 했지만, 만약 어플리케이션 숫자가 지금보다 훨씬 많다면 추후 페이지 삭제나 추가, 변경이 필요한 때에 제대로 관리가 될 수 있을까?"

 

예를 들어보자. 만약 필자가 /donwloads라는 URL 주소를 /down_down이라는 주소로 변경해야 한다고 하자. 그럼 기본 urls.py의 donwload 하위 4개의 URL 주소를 동일하게 down-down으로 변경해주어야 한다. 물론 vi를 위시한 여타 편집기에서 단어 변환 기능을 제공하긴 하지만, 아무래도 관리의 측면에서는 비효율적일 수 밖에 없다.

 

그럼, 어떻게 하면 이들 하위 주소를 효과적으로 관리할 수 있을까? 다시 기본 urls.py 파일을 열어보자.

 

기본 urls.py 파일의 위쪽 주석 부분은, urls.py의 작성 방법에 대해 설명하고 있다. 크게  function views, class-based views 그리고 inlcuding URLconf 3 가지 방식이 있다.

 

지금까지 필자가 한 방식은 views 파일의 특정 함수를 찾아 그 함수 내 코드를 실행하도록 하는 function views 방식이었는데, 이 방식은 지금과 같이 URL이 두 단계 이상의 하위 구조로 이루어진 경우, 기본 urls.py 파일에 정의하기가 매우 까다로운 방법이다. 

 

주석의 마지막 including another URLconf 방식이 지금 필자가 진행하려는 방식인데, 이는 특정 어플리케이션에 urls.py 파일을 정의한 뒤, 기본 urls.py 파일에 어플리케이션 urls.py 파일을 include 하여 관리의 편의성을 증진하키는 방식이다. 위의 주석 내용을 예로 들어보자.

 

만약 필자가 blogs라는 주소 아래 하위 URL로 /test 와 /test2를 만든다고 가정해보자. 그럼, 기본 urls.py 파일에는 blog/에 대한 Path함수를 정의하되, 두 번째 인자에는 views 파일이 아니라, blog 폴더(어플리케이션) 안에 정의된 urls.py 파일을 참조하도록 하는 것이다. 폴더 내 urls.py는 /test와 /test2 URL에 대해서만 path 함수로 정의되어 있으며, 기본 urls.py에 의해 폴더 내 urls.py 파일이 참조되기 때문에, /blog/test와 /blog/test2 URL에 대한 동작의 정의가 가능해진다.

 

확실히 말로만 설명하려니 어렵다. 직접 실습을 진행해보자.

 

 

1. 기본 urls.py 파일을 include 함수로 정의

 

먼저 기본 urls.py 파일을 include 방식을 사용하여 어플리케이션의 각 urls.py 파일을 참조할 수 있도록 만들어야 한다. 이 때 사용하는 include 함수는 django의 기본 폴더가 저장된 경로 안의 urls 폴더에 정의되어 있으므로, import 문을 사용하여 include 함수를 호출해주어야 한다.

 

from django.urls import include  

 

 

기본으로 사용하는 path 함수 역시 django.urls 경로 밑에 정의되어 있기 때문에, 해당 코드 뒤에 include를 추가만 하면 된다 (import 문의 사용법에 대해서 알고 싶으신 분들은 여기를 참고하자).

 

include 문을 사용할 준비는 되었으니, 본격적으로 각 어플리케이션에 대한 정의를 진행해보자. 

 

include 함수는 path 함수의 두 번째 인자에 사용하며, include 함수의 인자는 참조하고자 하는 urls 파일을 명시해주면 된다. 필자의 경우, main/ 은 main.urls.py 파일을, about/은 about.urls.py 파일을, downloads/는 downloads.urls.py 파일을 참조하도록 할 것이다.

 

 

혹은, 조금 더 알아보기 쉽게, from ... import 문을 사용하여 아래와 같이 나타내는 것도 가능하다.

이전 스크린샷과 달리 따옴표가 include 내애 작성되지 않은 것을 반드시 확인하자. as 문에 의해 *_urls가 모두 변수로 표현되기 때문이다

위와 같이 작성되면, 매인 주소인 https://172.30.1.50:8080이 호출되는 경우, main 어플리케이션의 urls.py 파일을 참조하여 하위 경로가 정의된 내용을 확인하게 된다. https://172.30.1.50:8080/admin과 https://172.30.1.50:8080/downloads 역시 마찬가지로 각각 about과 downloads 어플리케이션의 urls.py 파일을 참조하여 해당 주소의 하위 URL 경로에 맵핑된 views 파일을 참조하게 된다. 

 

여기까지 작성이 완료되었다면, 기본 urls.py 파일에 include된 urls.py 파일을 각 어플리케이션 폴더에서 정의해주어야 한다.

 

 

 

2. 어플리케이션 폴더 내에 urls.py 파일 생성

 

어플리케이션이 생성되면, 생성한 어플리케이션 이름으로 폴더가 만들어지며, 각 폴더 내에는 기본적으로 제공되는 파일이 존재하고 있음을 확인할 수 있다. 

 

그러나, 어플리케이션 폴더 내에는 urls.py가 기본으로 생성되지 않기 때문에 include 방식으로 URL을 정의하기 위해서는 수동으로 urls.py 파일을 각 어플리케이션 폴더 내에 만들어주저야 한다.

 

 

이제 각 어플리케이션의 urls.py 파일을 작성해보자. 작성 방식은 기본 urls.py 파일과 크게 다르지 않다. 먼저 main URL의 경우, main 외에 다른 하위 경로가 존재하지 않으므로, 다음과 같이 작성이 가능하다.

 

/about과 /donwloads/의 경우, 매인 페이지와 달리 하위 URL 주소가 존재하기 때문에, 아래과 같이 폴더 내 urls.py를 작성해 줄 수 있다.

 

 

 

각 어플리케이션 URL 주소로 지정한 views 파일의 함수는 이전의 포스팅과 동일한 방식으로 작성하여 진행하면 된다. views 파일이 참조하는 html 파일 역시 각 어플리케이션의 templates 폴더에 위치시켜 django가 인식할 수 있도록 만들면 된다. 이와 관련한 자세한 내용은 이전의 포스팅을 참조하자.

 

< main.views.py 파일 >

<about.views.py 파일 >

< downloads.view.py 파일 >

 

 

위와 같이 작성이 완료되고 서버를 구동하면, 필자가 의도한대로 모든 페이지가 정상적으로 나타남을 확인할 수 있다.

 

< 매인 페이지, https://172.30.1.50:8080 >

 

< about 페이지, https://172.30.1.50:8080/about  -  하위 '', '/apps', '/help', '/quotes'>

 

< downloads 페이지, https://172.30.1.50:8080/downloads, 하위 '', '/windows', '/mac-osx', '/other' >

 

 

 

 

 

 

3. templates 파일 명명 시 주의사항

 

현재 필자가 구성한 서버의 매인 홈페이지의 html 파일 이름은 index다. 필자가 다른 URL의 매인 페이지는 {어플리케이션이름}_index로 html 파일을 명명했다. 그런데, 매인페이지의 html 파일 이름을 모두 동일하게 index로 하면 어떻게 될까?

 

"그야 당연히 urls와 views 파일에 지정된대로 index 파일을 찾아가니 문제없지 않을까요??"

 

필자도 처음에는 이렇게 생각을 했다. 그런데, 모든 매인 페이지 이름을 index.html로 통일하니, 페이지 맵핑이 제대로 진행되지 않는 문제가 발생한다. 말로는 어려우니 아래에서 직접 내용을 확인해보자.

 

<main.views.py 파일 매인 페이지: index.html >

< about.views.py 파일 매인 페이지: index.html >

< downloads.views.py 파일 매인 페이지: index.html >

 

모든 어플리케이션의 templates 내에 정의된 매인 페이지 html 파일 이름 역시 모두 index.html로 변경하였다.

 

이제 서버를 실행하고, 기본 페이지(https://172.30.1.50:8080), about 매인 페이지(172.30.1.50:8080/about), downloads 매인 페이지(https://172.30.1.50:8080)에 접속을 시도해보자. 모두 기본 매인 페이지 내용만 나타날 것이다.

 

 

이 당황스러운 상황은 어떻게보면 너무나도 당연한 현상이다. 필자가 이전 포스팅에서도 언급했듯이, Django는 views.py에 정의된 페이지 파일을 검색할 때, 기본 settings.py의 INSTALLED_APPS 폴더 내 templates 폴더를 순차적으로 검색(templates 폴더가 없는 경우 건너뛴다) 하면서 views.py에 정의된 페이지 파일을 찾는다. 그런데, INSTALLED_APPS의 가장 첫 머리에는 main 어플리케이션이 정의되어 있고, 이 폴더 내에는 index.html 파일이 존재하기 때문에 about과 downloads의 views.py 파일에 정의된 index.html 파일 역시, main 폴더 templates의 index.html 파일을 참조할 수 밖에 없는 것이다. 

 

 

만약, INSTALLED_APPS의 순서가 main이 첫 번째가 아니라, about이 첫 번째에 정의된다면, 모든 매인 페이지는 about 매인 페이지가 나타나게 된다.

이 녀석 때문에 3주간 머리가 아팠다...

 

따라서, 각 페이지의 html 파일 이름을 각기 다르게 명명하거나, 반드시 동일한 이름(index.html)을 사용해야하는 경우, templates 내에 별도의 폴더를 만들어 따로 관리를 하는 방법을 사용한다(Django 매뉴얼을 보면 후자를 많이 사용하는 듯 하다. 아래와 같이 사용한다)

 

 

 

서버 실행 결과, index.html 파일이 여러 개 있음에도 불구하고, 이전과 달리 정상적으로 페이지가 렌더링되는 것을 확인할 수 있다.

 

 

 

**  urls.py 파일을 작성하는 방식에 Class를 사용하는 방식도 있는데, 얼핏 찾아보니 models.py 파일에 대해 먼저 익숙해 진 뒤, 넘어가야하는 내용인 듯 하다. 따라서, urls.py의 마지막 작성 방식인 class view 방식은 추후 포스팅을 진행하려 한다.

 

 

 

Fin.

반응형

댓글