Creation our home page
지금까지 했던 것은
단지 프로젝트 생성, Model 생성, 관리자 앱 추가 및 조작을 해봤다.
하지만
이것 만으로는 우리가 원하는 하나의 홈 페이지
즉, 애플리케이션을 만들었다고는 할 수 없다.
왜냐하면
아직 View와 Template를 생성하지 않았기 때문이다.
단지 Model을 생성해서 데이터를
추가 수정 및 삭제 했을 뿐이다.
그렇다면
다음에 해야 될 것은 당연히
View와 Template를 생성한 후에
우리가 원하는 애플리케이션을 완성하는 것이다.
우선 아래의 데이터의 흐름과 HTTP 요청 및 응답을 처리하는데에
필요한 요소들에 대해 살펴볼 필요가 있다.
블로그 내의 MVC와 MVT비교 글에 대한 이해가 있다면
이해하는데에 큰 문제는 없을 것이다.
① resource URLs 정의하기
이 버전의 LocalLibrary는
유저들에게는 읽기 전용이기 때문에
사이트의 방문 페이지 그리고 책들과 저자들에 대한
목록 및 Detail View들을 보여주는 페이지만 제공해주면 된다.
필요한 URL은 아래와 같다.
Index Page 만들기
첫 번째로 만들 페이지는 index page(catalog/)이다.
즉, 해당 앱에 진입했을 때 보여지는 첫번째 페이지를 말한다.
① URL Mapping
이전에 locallibrary/urls.py 파일을 업데이트 했던것을 기억할 것이다.
catalog/로 시작하는 URL을 받았을때,
URLConf 모듈인 catalog.urls가 나머지 문자열을 처리하도록 하기 위해
이전에 업데이트를 했었다.
이전에 했던 부분이 위의 빨간색 박스이다.
Django는 import 함수 django.urls.include()를 만날 때 마다
지정된 마지막 문자에서 문자열을 나누고,
나머지 부분 문자열을 포함된 URLconf 모듈로 보냅니다.
또한 /catalog/urls.py이라는 URLConf 모듈을 위한
파일(place holder)도 생성하였다.
| urlpatterns = [ path('', views.index, name='index'), ] | cs |
위와 같이 코드를 추가 하자.
path() 함수에 대한 내용은
이전에 작성했던 아래의 포스팅을 참고하기 바란다.
이 path() 함수는 name 매개 변수를 지정하는데,
URL Mapping을 위한 고유 ID이다.
이 이름의 Mapper를 반전(reverse())시켜
URL를 동적으로 생성할 수 있다.
URL을 동적으로 생성하면
홈페이지를 바꿨을 때 따로 수정하지 않아도 되기 때문에
반전된 URL Mapper를 사용하는 것이 훨씬 유연하다.
② (함수 기반의) View
View는 Http Request를 처리하고
DB에서 Request 된 데이터를 가져오고
Html 템플릿을 이용해서
데이터를 HTML 페이지에 렌더링 하고,
그리고 생성된 HTML을 Http Response로 반환하여
페이지를 보여주는 함수이다.
catalog/views.py를 연 후에
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | from django.shortcuts import render # Create your views here. from catalog.models import Book, Author, BookInstance, Genre def index(request): """View function for home page of site.""" # Generate counts of some of the main objects num_books = Book.objects.all().count() num_instances = BookInstance.objects.all().count() # Available books (status = 'a') num_instances_available = BookInstance.objects.filter(status__exact='a').count() # The 'all()' is implied by default. num_authors = Author.objects.count() context = { 'num_books': num_books, 'num_instances': num_instances, 'num_instances_available': num_instances_available, 'num_authors': num_authors, } # Render the HTML template index.html with the data in the context variable return render(request, 'index.html', context=context) | cs |
위와 같이 코드를 추가하자.
③템플릿(Template)
Template는 HTML와 같은 파일의 구조나
레이아웃을 정의하는 텍스트 파일이다.
Django는 일반적으로 애플리케이션 안에서
templates라고 이름지어진 경로 안에서 자동적으로
템플릿을 찾는다.
1) Template 확장 하기
아래의 코드는 base_generic.html 파일의 기본 템플릿 샘플이다.
| <!DOCTYPE html> <html lang="en"> <head> {% block title %}<title>Local Library</title>{% endblock %} </head> <body> {% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %} {% block content %}<!-- default content text (typically empty) -->{% endblock %} </body> </html> | cs |
특정한 View를 위해 템플릿을 정의할 땐
먼저 extends 템플릿 태그를 이용해서 기본 템플릿을 지정해야한다.
| {% extends "base_generic.html" %} {% block content %} <h1>Local Library Home</h1> <p>Welcome to LocalLibrary, a website developed by <em>Mozilla Developer Network</em>!</p> {% endblock %} | cs |
예를 들어
위의 코드는 extends 템플릿 태그의 사용과
content 블록(block)을 재정의 하는 방법을 보여준다.
생성된 HTML은 기본 템플릿에서 정의된 코드와 구조를 포함한다.
LocalLibrary 기본 Template
새로운 파일인 base_generic.html파일을
/locallibrary/catalog/templates/ 경로 안에 생성해
아래의 코드를 추가하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!DOCTYPE html> <html lang="en"> <head> {% block title %}<title>Local Library</title>{% endblock %} <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <!-- Add additional CSS in static file --> {% load static %} <link rel="stylesheet" href="{% static 'css/styles.css' %}"> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-sm-2"> {% block sidebar %} <ul class="sidebar-nav"> <li><a href="{% url 'index' %}">Home</a></li> <li><a href="">All books</a></li> <li><a href="">All authors</a></li> </ul> {% endblock %} </div> <div class="col-sm-10 ">{% block content %}{% endblock %}</div> </div> </div> </body> </html> | cs |
또한 /locallibrary/catalog/static/css/
경로에 템플릿의 디자인을 제공하는 styles.css 파일을 생성하고
위의 코드를 추가하자. 하자.
색인(Index) Template
새로운 HTML 파일 index.html을
/locallibrary/catalog/templates/ 경로 안에 생성해
아래의 코드를 추가하자.
| {% extends "base_generic.html" %} {% block content %} <h1>Local Library Home</h1> <p>Welcome to LocalLibrary, a website developed by <em>Mozilla Developer Network</em>!</p> <h2>Dynamic content</h2> <p>The library has the following record counts:</p> <ul> <li><strong>Books:</strong> {{ num_books }}</li> <li><strong>Copies:</strong> {{ num_instances }}</li> <li><strong>Copies available:</strong> {{ num_instances_available }}</li> <li><strong>Authors:</strong> {{ num_authors }}</li> </ul> {% endblock %} | cs |
{% block content %} ~ {% endlock %} 사이에
표시하고 싶은 View의 정보를 코딩한다.
위의 코드에서 알 수 있듯이
변수들은 이중 괄호( {{ }} )로 감싸져있고,
태그들은 ({% %})단일 중괄호와
퍼센트 기호로 감싸져 있는 것을 알 수 있다.
다만 주의해야 할 것은
변수들의 이름은 Key로 정해진다는 것이다.
이 Key들은 View의 render()함수 안의 context
사전형 자료형에 전달하는 Key이다.
변수들은 템플릿이 render()함수에 의해
렌더링 될 때 연관된 값들로 대체 될 것이다.
Template에 정적 파일 참조하기(Referencing)
결국 이 프로젝트는 자바스크립트, CSS 그리고 이미지를 포함하는
정적 리소스들을 사용할 가능성이 높다.
하지만 Django는 이 위치를 알 수 없기 때문에
STATIC_URL 전역 설정을 기준으로
템플렛에서의 위치를 특정할 수 있도록 한다.
| <!-- Add additional CSS in static file --> {% load static %} <link rel="stylesheet" href="{% static 'css/styles.css' %}"> | cs |
위의 코드와 같이
템플렛 안에서 먼저 템플릿 라이브러리를 추가하기 위해
static을 지정하는 load 템플렛 태그를 호출한다.
| {% load static %} <img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="UML diagram" style="width:555px;height:540px;"> | cs |
비슷한 방식으로 위와 같이
이미지를 페이지에 추가할 수도 있다.
정적 파일들에 대한 자세한 내용은
아래의 공식 도큐먼트를 참고하길 바란다.
Template을 찾을 수 있는 곳 설정하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR, 'templates'), ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] | cs |
위의 코드와 같이 settings.py 파일 안에
TEMPLATES 변수에 빨간색 박스와 같이 코드를 추가하자.
그렇다면 이제 실제 Model에 View와 Template를
그리고 이전 튜토리얼에는 없었던 CSS까지 추가 한
Locallibrary 애플리케이션을 사용해보자.
버그가 없다면 위와같은 화면이 나온다.