Django 웹사이트 만들기 8. css로 화면 꾸미기
지금까지 질문과 답변을 등록하고 조회하는 아래와 같은 사이트를 만들어보았다. 지금까지 만든 투박한 화면을 꾸며보는 방법을 알아보자.
1. 웹 페이지에 스타일시트 적용하기
1-1. 설정 파일에 스태틱 디렉터리 위치 추가하기
config/settings.py 파일을 열어 STATICFILES_DIRS에 스태틱 디렉터리 경로를 추가한다. BASE_DIR / 'static'은 E:/projects/mysite/static을 의미한다.
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
1-2. 스태틱 디렉터리 만들고 스타일시트 작성하기
프로젝트 루트 디렉터리에 static이라는 이름의 디렉터리를 생성한다. 루트 디렉터리는 E:/projects/mysite를 의미한다.
mkdir static
새로 만든 static 디렉터리에 style.css 파일을 만들어 다음 코드를 작성하자.
답변을 등록할 때 사용하는 textarea를 100%로 넓히고, <답변등록> 버튼 위에 margin을 10px 추가했다.
textarea {
width:100%;
}
input[type=submit] {
margin-top:10px;
}
1-3. 질문 상세 템플릿에 스타일 적용하기
pyweb/question_detail.html 파일에 style.css 파일을 적용해보자. 스태틱 파일을 사용하기 위해서는 템플릿 파일 맨 위에 {% load static %} 태그를 삽입하고, link 엘리먼트 href 속성에 {% static 'style.css' %}를 적는다.
{% load static %}
<link rel="stylesheet" type="text/css" herf="{% static 'style.css' %}">
<h1>{{ question.subject }}</h1>
(... 생략 ...)
2. 부트스트랩 활용하여 더 쉽게 화면 꾸미기
1-1. 부트스트랩 설치하기
https://getbootstrap.com/docs/4.5/getting-started/download/ 에 접속하여 부트스트랩 설치파일을 내려받는다.
설치파일의 압축을 풀고 css 폴더 하위의 bootstrap.min.css 파일만 복사해 mysite/static 디렉터리에 저장한다.
2-2. 질문 목록 템플릿에 부트스트랩 적용하기
pyweb/question_list.html 파일에 부트스트랩을 적용하기 위해 {% load static %} 태그와 link 엘리먼트를 추가한다.
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
(... 생략 ...)
이어서 부트스트랩을 이용하여 템프릿을 다음과 같이 재구성하자. container, my-3, thread-dark 등이 부트스트랩이 제공하는 클래스이다.
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
<div class="container my-3">
<table class="table">
<tread>
<tr class="thread-dark">
<th>번호</th>
<th>제목</th>
<th>작성일자</th>
</tr>
</tread>
<tbody>
{% if question_list %}
{% for question in question_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>
<a href="{% url 'pyweb:detail' question.id %}">
{{ question.subject }}
</a>
</td>
<td>{{ question.create_date }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="3">질문이 없습니다.</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
다음과 같이 부트스트랩이 적용된 것을 볼 수 있다. 부트스트랩에 대한 상세한 설명은 넘어갈 것이다.
2-3. 질문 상세 템플릿에 부트스트랩 사용하기
질문 상세 템플릿도 부트스트랩을 적용해보자.
/mysite/templetes/pyweb/question_detail.html
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
<div class="container my-3">
<h2 class="border-bottom py-2">{{ question.subject }}</h2>
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;">{{ question.content }}</div>
<div class="d-flex justify-content-end">
<div class="badge badge-light p-2">
{{ question.create_date }}
</div>
</div>
</div>
</div>
<h5 class="border-bottom my-3 py-2">{{question.answer_set.count}}개의 답변이 있습니다.</h5>
{% for answer in question.answer_set.all %}
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;">{{ answer.content }}</div>
<div class="d-flex justify-content-end">
<div class="badge badge-light p-2">
{{ answer.create_date }}
</div>
</div>
</div>
</div>
{% endfor %}
<form action="{% url 'pyweb:answer_create' question.id %}" method="post" class="my-3">
{% csrf_token %}
<div class="form-group">
<textarea name="content" id="content" class="form-control" rows="10"></textarea>
</div>
<input type="submit" value="답변등록" class="btn btn-primary">
</form>
</div>
3. 표준 HTML과 템플릿 상속 사용해 보기
지금까지 작성한 템플릿들은 표준 HTML 구조가 아니다. 지금부터 표준 HTML 구조로 템플릿을 변경해보자.
3-1. 템플릿 파일의 기본 틀 작성
템플릿 파일의 기본 틀인 base.html 템플릿을 작성하자. 모든 템플릿이 공통적으로 사용할 내용들을 가지고 있는 파일이라고 생각하면 된다.
{% load static %}
<!doctype html>
<html lang="ko">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
<!-- pyweb CSS -->
<link rel="stylesheet" type="text/css" href="{% static 'style.css' %}">
<title>Hello, pyweb</title>
</head>
<body>
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
{% block content %}
{% endblock %}
<!-- 기본 템플릿 안에 삽입될 내용 End -->
</body>
</html>
body 엘리먼트에 {% block content %}와 {% endblock %} 템플릿 태그가 있다. 이 부분이 base.html 템플릿 파일을 상속한 파일에서 구현해야 하는 영역이 된다. question_list.html 템플릿을 다음과 같이 작성한다.
3-2. 질문 목록 템플릿 수정하기
question_detail.html 파일을 다음과 같이 수정한다.
{% extends 'base.html' %} #기존 코드 삭제후 추가
{% block content %}
<div class="container my-3">
<table class="table">
<thead>
<tr class="thead-dark">
<th>번호</th>
<th>제목</th>
<th>작성일자</th>
</tr>
</thead>
<tbody>
{% if question_list %}
{% for question in question_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>
<a href="{% url 'pyweb:detail' question.id %}">
{{ question.subject }}
</a>
</td>
<td>{{ question.create_date }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="3">질문이 없습니다.</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
{% endblock %} #추가
base.html 템플릿을 상속받기 위해 {% extends 'base.html' %} 템플릿 태그를 사용했다. 그리고 {% block content %}와 {% end block %} 사이에 question_list.html 파일에서만 사용할 내용을 작성했다.
3-3. 질문 상세 템플릿 수정하기
question_detail.html 파일을 다음과 같이 수정한다.
{% extends 'base.html' %}
{% block content %}
<div class="container my-3">
<h2 class="border-bottom py-2">{{ question.subject }}</h2>
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;">{{ question.content }}</div>
<div class="d-flex justify-content-end">
<div class="badge badge-light p-2">
{{ question.create_date }}
</div>
</div>
</div>
</div>
<h5 class="border-bottom my-3 py-2">{{question.answer_set.count}}개의 답변이 있습니다.</h5>
{% for answer in question.answer_set.all %}
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;">{{ answer.content }}</div>
<div class="d-flex justify-content-end">
<div class="badge badge-light p-2">
{{ answer.create_date }}
</div>
</div>
</div>
</div>
{% endfor %}
<form action="{% url 'pyweb:answer_create' question.id %}" method="post" class="my-3">
{% csrf_token %}
<div class="form-group">
<textarea name="content" id="content" class="form-control" rows="10"></textarea>
</div>
<input type="submit" value="답변등록" class="btn btn-primary">
</form>
</div>
{% endblock %}
3-4. 기존 style.css 파일 내용 지우기
부트스트랩을 사용하기 위해 style.css 파일의 내용을 모두 지워준다.