답변등록 폼
질문 상세 템플릿에 다음처럼 답변을 저장할 수 있는 폼을 추가하자.
<h1>{{ question.subject }}</h1> <div> {{ question.content }} </div> <form action="{% url 'pybo:answer_create' question.id %}" method="post"> {% csrf_token %} <textarea name="content" id="content" rows="15"></textarea> <input type="submit" value="답변등록"> </form> |
php 와 유사해보인다. 포스트 방식으로 textarea의 내용을 제출하게 된다.
답변의 내용을 입력할 수 있는 텍스트창과 답변을 저장 할 수 있는 "답변등록" 버튼을 추가했다. 답변 저장을 위한 URL은 form 태그의 action 속성에 {% url 'pybo:answer_create' question.id %}로 지정했다.
form 태그 바로 밑에 보이는 {% csrf_token %}은 보안에 관련된 항목으로 form으로 전송한 데이터가 실제 웹 페이지에서 작성한 데이터인지를 판단해 주는 가늠자 역할을 한다. 만약 해커가 엉뚱한 방법으로 데이터를 전송할 경우에는 서버에서 발행한 csrf_token 값과 해당 툴에서 보낸 csrf_token 값이 일치하지 않기 때문에 오류가 발생할 것이다.
따라서 form 태그 바로 밑에 {% csrf_token %} 태그를 항상 위치시키도록 해야 한다.
URL 매핑
이제 질문 상세 템플릿을 위와 같이 고친 후 페이지에 접속해보자.
당연하게도 접속이 안된다. answer_create 별칭을 아직 안만들어주었기때문. 즉 url 매핑을 해주지않았다
from django.urls import path from . import views app_name = 'pybo' urlpatterns = [ path('', views.index, name='index'), path('<int:question_id>/', views.detail, name='detail'), path('answer/create/<int:question_id>/', views.answer_create, name='answer_create'), ] |
url매핑을 해주자.
http://localhost:8000/pybo/answer/create/2(ex_id)/
와 같이 url이 접속되게 설정하자.
views.answer_create 메소드에 매핑해놨는데 현재 views.py에 answer_create 메소드가 정의 되어 있지않다.
views.py로 이동하자
from django.shortcuts import render, get_object_or_404, redirect from django.utils import timezone from .models import Question (... 생략 ...) def answer_create(request, question_id): """ pybo 답변등록 """ question = get_object_or_404(Question, pk=question_id) question.answer_set.create(content=request.POST.get('content'), create_date=timezone.now()) return redirect('pybo:detail', question_id=question.id) |
아까 템플릿파일에 작성한 content를 가져오기위해, request.POST.get('content')를 통해서 답변 내용을 가져오고
객체를 생성해서 저장한다.
그리고 답변을 생성한 후 질문 상세화면을 다시 보여주기 위해 redirect 함수를 사용했다.
여기서 redirect 함수는 페이지 이동을 위한 함수
def answer_create(request, question_id): """ pybo 답변등록 """ question = get_object_or_404(Question, pk=question_id) answer = Answer(question=question, content=request.POST.get('content'), create_date=timezone.now()) answer.save() return redirect('pybo:detail', question_id=question.id) |
데이터를 생성할때 사용한것처럼 Answer 모델을 가지고 객체를 생성하는 이 방식도 똑같다.
이게 좀 더 지금 당장에는 나한테 와닿으니 기억하자.
답변 조회
question_detail.html 템플릿 파일에 질문에 대한 답변들을 출력하려고 한다.
<h5>{{ question.answer_set.count }}개의 답변이 있습니다.</h5> <div> <ul> {% for answer in question.answer_set.all %} <li>{{ answer.content }}</li> {% endfor %} </ul> </div> |
질문에 대한 답변에 대한 객체를 question.answer_set 객체로 생성했다.
question.answer_set.count ==> 답변이 몇개 인지 반환
answer.content ==> answer 객체의 content를 출력
답변을 등록한 결과
위와 같이 작성된다.
php 에 css 가 있듯이 장고도 css파일을 이용한 디자인을 지원한다.
위와 같이 허접한 박스모양은 상당히 불쾌하다.
스태틱(static) 디렉토리
스타일시트 파일은 장고의 스태틱 디렉토리에 저장해야 한다. 스태틱 디렉토리도 템플릿 디렉토리에 했던 방식과
마찬가지로, config/settings.py 파일에 등록해야한다.
다음과 같이 수정하자.
(... 생략 ...) STATIC_URL = '/static/' STATICFILES_DIRS = [ BASE_DIR / 'static', ] (... 생략 ...) |
static 폴더를 생성하자.
그리고 스타일 시트 파일을 작성한다.
textarea { width:100%; } input[type=submit] { margin-top:10px; } |
답변 등록시 사용하는 텍스트 창의 넓이를 100%로 하고 "답변등록" 버튼 상단에 10 픽셀의 마진을 설정했다.
템플릿에 스타일시트 적용
질문 상세 템플릿에 방금 작성한 스타일 시트를 적용해보자.
question_detail.html 에 최상단에 다음과 같이 작성한다.
{% load static %} <link rel="stylesheet" type="text/css" href="{% static 'style.css' %}"> <h1>{{ question.subject }}</h1> (... 생략 ...) |
static에 스타일시트가 있으므로 load static을 한 뒤에
스타일 시트를 적용한다.
php를 미리 공부해두어서 그런지 유사한 점이 많은것같다.
파이참을 가지고 웹을 디자인하고 있으니 조금 신기하다
'개인 공부 > 개발' 카테고리의 다른 글
장고 폼(form) (0) | 2021.08.09 |
---|---|
부트스트랩과 html (0) | 2021.08.08 |
장고 URL과 네임스페이스 (0) | 2021.08.04 |
장고 조회와 템플릿 (0) | 2021.08.04 |
장고 관리자 (0) | 2021.08.02 |
댓글