본문 바로가기
개인 공부/개발

장고 데이터 저장과 스타일 시트

by 아메리카노와떡볶이 2021. 8. 5.
728x90

답변등록 폼

질문 상세 템플릿에 다음처럼 답변을 저장할 수 있는 폼을 추가하자.

<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를 미리 공부해두어서 그런지 유사한 점이 많은것같다.

파이참을 가지고 웹을 디자인하고 있으니 조금 신기하다

728x90

'개인 공부 > 개발' 카테고리의 다른 글

장고 폼(form)  (0) 2021.08.09
부트스트랩과 html  (0) 2021.08.08
장고 URL과 네임스페이스  (0) 2021.08.04
장고 조회와 템플릿  (0) 2021.08.04
장고 관리자  (0) 2021.08.02

댓글