이전 포스트
[Django] 1. 개발 환경 설정 https://wroni.tistory.com/4
[Django] 2 - 1. URL과 View https://wroni.tistory.com/5
[Django] 2 - 2. 모델 https://wroni.tistory.com/6
[Django] 2 - 3. 장고 관리자 https://wroni.tistory.com/7
2 - 4. 조회와 템플릿
1. 질문 목록
이제 로컬 호스트에 /pybo를 요청하면 질문들을 조회할 수 있도록 할 것이다.
웹 서버를 구동시키면 저번에 만들어 놓은 "안녕하세요 pybo에 잘 오셨습니다."가 뜨고 있다.
이제 질문 목록이 뜨도록 pybo\views.py 파일에 index 함수를 변경하자
파일 : C:\projects\mysite\pybo\views.py
from django.shortcuts import render
from .models import Question
def index(request):
"""
pybo 목록 출력
"""
question_list = Question.objects.order_by('-create_date')
context = {'question_list': question_list}
return render(request, 'pybo/question_list.html', context)
* pycharm 캡쳐 상에는 index 함수에 question_list = Question.objects.order_by('-create_data')로 되어 있는데
data가 아니라 date다! 오류 뜨고나서야 알았다,,, 오타 주의하자(본인은 date를 data로 쓰는 실수를 자주 범하고 있다... 오타 주의)
질문 목록 데이터는 Question.objects.oreder_by('-create_date')로 얻을 수 있으며, order_by로 작성일시 역순으로 정렬하고 있다. -가 없으면 순방향, -가 붙어있으면 역방향이다. render 함수는 파이썬 데이터를 템플릿에 적용한 HTML을 반환하는 함수이다.
2. 템플릿 디렉터리
render 함수로 'pybo/question_list.html'을 반환하기로 했으니, 이제 해당 디렉터리에 html을 만들어야 할 순서다.
템플릿 파일을 생성하기 전에 템플릿 파일을 저장할 디렉터리를 만들자.
먼저 템플릿을 저장할 디렉터리를 config/settings.py 파일에 TEMPLATES 항목에 추가해야 한다.
파일 : C"\projects\mysite\config\settings.py
'DIRS' 부분에 [BASE_DIR / 'templates'], 를 추가해준다.
DIRS 템플릿 디렉터리를 여러 개 등록할 수 있도록 리스트로 되어 있다.
BASE_DIR / 'templates' 에서 BASE_DIR은 C:\projects\mysite이므로 추가한 디렉터리의 전체 경로는 다음과 같다
C:\projects\mysite\templates
해당 디렉터리가 없으므로 명령 프롬프트에서 생성하자
장고는 DIRS에 설정한 디렉터리 이외에도 앱 디렉터리 바로 하위에 있는 templates 디렉터리도 템플릿 디렉터리로 인식한다
C:\projects\mysite\templates\pybo
이제 해당 디렉터리를 사용할 것이다. 공통으로 사용하는 템플릿은 templates에 저장할 것이다.
3. 템플릿 파일
이제 드디어 템플릿 파일을 만들 것이다. index 함수에서 render 한 html 파일은 pybo\question_list.html이었다.
C:\projects\mysite\templates\pybo\question_list.html
파일 : C\projects\mysite\templates\pybo\question_list.html
{% if question_list %} # question_list가 있으면
<ul>
{% for question in question_list %} # question_list for loop가 돌고
<li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li> # 질문 id, 제목 출력
{% endfor %} # for loop문 끝내는 선언
</ul>
{% else %} # question_list가 없으면
<p>질문이 없습니다.</p> # 질문 없다고 출력
{% endif %} # if문 끝내는 선언
Jinja template 문법을 알고 있으면 편하다. 잘 모르겠다면 주석을 참고하면 된다.
주의할 점은 for loop문 끝내려면 {% endfor %}를 선언해야 하고, if문 끝내려면 {% endif %}를 선언해야 한다.
4. 템플릿 태그
템플릿 문법을 간단하게 보자면,
forloop
forloop 속성 | 설명 |
forloop.counter | 루프내의 순서로 1부터 표시 |
forlop.counter() | 루프내의 순서로 0부터 표시 |
forloop.first | 루프의 첫번째 순서인 경우 True |
forloop.last | 루프의 마지막 순서인 경우 True |
객체
객체 | 예시 |
{{ 객체 }} | {{ item }} |
{{ 객체.속성 }} | {{ question.id }} {{ question.subject }} |
이제 테스트해보자. /pybo 화면이 어떻게 뜰까
초반에 작성했던 Question 제목이 잘 조회되고 있다.
5. 질문 상세
질문 목록 중 한 개를 클릭해보자.
엥 404가 뜬다. 하긴 URL 연결을 안 했으니 당연하다.
질문을 클릭한 후 링크를 보면 http://localhost:8000/pybo/2/ 이다. URL의 의도는 id가 2인 Question을 상세 조회하는 것이다.
그렇다면, urls.py로 가서 코드를 수정하자.
파일 : C:\projects\mysite\pybo\urls.py
path('<int:question_id>/', views.detail),
해당 코드를 추가해준다. 코드는 question_id를 int로 받고, views.detail 함수가 실행된다는 뜻이다.
이제 views.py에 가서 detail 함수를 생성해야 한다.
파일 : C:\projects\mysite\pybo\views.py
def detail(request, question_id):
"""
pybo 내용 출력
"""
question = Question.objects.get(id=question_id)
context = {'question' : question}
return render(request, 'pybo/question_detail.html', context)
해당 코드를 입력하면 detail 함수 호출시 request와 question_id 매개변수로 전달된다.
question_id에는 URL 매핑 때 저장된 question_id가 전달된다.
이제 http://localhost:8000/pybo/2 페이지를 요청하면 detail 함수의 question_id에는 2라는 값이 전달된다.
detail 함수도 작성하였고, 이제 question_detail.html을 작성하자.
파일 : C:\projects\mysite\templates\pybo\question_detail.html
<h1>{{ question.subject }}</h1>
<div>
{{ question.content }}
</div>
앞에서 설명한 것처럼, 해당 코드는 제목과 내용을 출력하고 있다.
subject는 h1 태크로 크게 나타내고, content는 div 태그로 작게 나타내고 있다.
http://localhost:8000/pybo/2 페이지를 요청해보자
잘 나오고 있다.
6. 오류 페이지
id가 30인 질문 페이지를 요청해보자. http://localhost:8000/pybo/30/ 요청하자.
오류 메세지를 보면 /pybo/30/이 존재하지 않는다고 뜨고 있다. 이 때 브라우저는 500 오류코드를 전달한다.
없는 데이터를 요청할 경우는 500 오류 페이지 보다 404 페이지를 리턴하는 것이 좋다.
/pybo/30/과 같이 없는 데이터를 요청할 때 404가 뜨도록 detail 함수를 수정하자.
파일 : C:\projects\mysite\pybo\views.py
from django.shortcuts import render, get_object_or_404 # get_object_or_404 추가
def detail(request, question_id):
...
# 수정할 내용
question = get_object_or_404(Question, pk=question_id)
...
import 부분에 get_object_or_404 추가해주고, detail 함수 안에 question 객체를 get_object_or_404로 수정한다.
기본키는 question_id를 나타낸다.
이제 다시 /pybo/30 페이지를 요청해보자
원하는대로 404 오류 페이지가 뜬다.
※ 본 내용은 django 공부 기록이며, 점프 투 장고를 참고하였습니다.
https://wikidocs.net/book/4223
'Django > Django 기초' 카테고리의 다른 글
[Django] 2 - 7. 스태틱 (0) | 2021.11.29 |
---|---|
[Django] 2 - 5. URL과 네임스페이스, 2 - 6. 데이터 저장 (0) | 2021.11.26 |
[Django] 2 - 3. 장고 관리자 (0) | 2021.11.24 |
[Django] 2 - 2. 모델 (0) | 2021.11.24 |
[Django] 2 - 1. URL과 View (0) | 2021.11.24 |