2023.04.16 - [파이썬을 이용한 웹구축] - 파이썬 게시글 목록과 댓글 css(bootstrap) html
파이썬 게시글 목록과 댓글 css(bootstrap) html
웹페이지 디렉토리를 코드로 열기 터미널 cmd 상태에서 ..\test\scripts\activate 우선 서버를 python manage.py runserver를 입력해서 서버를 열어준다. 게시글 목록이 정상적으로 열리는지 확인. 어제는 게시
ji7290.tistory.com
이전에는 게시글 목록과 댓글에 css를 넣어주고 작성버튼을 만들어주었다.
게시글 작성할 수 있는 폼을 만들어보자.
post method를 사용해야 전달되는 데이터를 보호할 수 있다.
board로가서 form.py를 생성해 준다
모델 클래스를 쓸꺼면 클래스안에 메타클래스가 반드시 있어야한다.
views.py로 돌아가서
QuestionForm을 import시켜준다.
from .forms import QuestionForm
forms에 있는 questionForm을 갖다쓰겠다.
def c_question(request):
form = QustionForm()
return render(request, 'board/q_form.html', {'form':form})
폼을 작성할 수 있는 함수를 만들어주고
반환값은 board/q_form.html으로 넘겨준다.
board 폴더에다가 - q_form.html을 생성해준다.
마찬가지로 q_form에도 base.html이 적용되도록
템플릿 태그를 작성해주고
폼태그는 메소드 post 메서드로 로 작성
{% csrf_token %} 필수태그도 작성
endblock태그까지 마무리해준다.
웹이미지
게시글 목록에서 글 작성버튼을 클릭하면 이렇게 글 작성 영역이 만들어진다.
하지만 글을 채우고 글 작성하기 버튼을 누르면 게시글 목록에 추가는 아직 되지 않고있다.
submit으로 제출은했지만 데이터에 저장을 못하고 있다.
views.py로 가서 코드를 수정해주자
c_question부분을 이렇게 수정해준다.
def c_question(request):
if request.method == 'POST':
form = QuestionForm(request.POST)
if form.is_valid():
question = form.save(commit=False)
question.create_date = timezone.now()
question.save()
return redirect('board:index')
else:
form = QuestionForm()
context = {'form' : form}
return render(request, 'board/q_form.html', context)
글작성이 정상적으로 리스트에 보여지게 된다.
q_form에서
form태그로 서버에 넘겨준다.
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h4 class="my-3 border-bottom pb-2">글 작성 </h4>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">글 작성하기
</form>
</div>
post형식으로 넘겨주면
path('question/create/', views.c_question, name='c_question'),
c_question함수가 동작을해서
from django import forms
from board.models import Question
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ['subject', 'content']
post된 항목을 가지고 QuestionForm항목을만들어서 사용하겠다.
def c_question(request):
if request.method == 'POST':
form = QuestionForm(request.POST)
if form.is_valid():
question = form.save(commit=False)
question.create_date = timezone.now()
question.save()
return redirect('board:index')
else:
form = QuestionForm()
context = {'form' : form}
return render(request, 'board/q_form.html', context)
#함수에서 return을 만나는 순간 함수는 종료가 된다.
최초의 글작성 눌렀을때는 else가 동작을 하고
else:
form = QuestionForm()
context = {'form' : form}
return render(request, 'board/q_form.html', context)
그 이후에 글 내용을 작성해서 글작성버튼을 누르면
q_form에 post라는 메소드가 데이터를 전송하게 되고
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">글 작성하기
</form>
urls.py 에서
path('question/create/', views.c_question, name='c_question'),
path경로가 동작을해서
views.py에
c_question 함수 -> if함수가 동작을 하게되고
def c_question(request):
if request.method == 'POST':
form = QuestionForm(request.POST)
if form.is_valid():
question = form.save(commit=False)
question.create_date = timezone.now()
question.save()
return redirect('board:index')
if함수
만약에 form안의 내용이 유효하다면
question이 받은 3개의 필드의 데이터를 save로 저장을 한후
question = form.save(commit=False)
question.create_date = timezone.now()
question.save()
return render로 board의 인덱스 q_list 화면으로 보내는 것이다.
return redirect('board:index')
이제 글 작성페이지를 꾸며보자.
forms.py로 가자
from django import forms
from board.models import Question
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ['subject', 'content']
widgets = {
'subject' : forms.TextInput(attrs={'class': 'form-control'}),
'content' : forms.Textarea(attrs={'class': 'form-control', 'rows' : 10 }),
}
labels = {
'subject' : '제목',
'content' : '내용',
}
widgets을 만들어쓰는이유는 q_forms에서 자동으로 만들어지게 해놔서
form에서 직접적인 지정이 불가능하다.
웹이미지
q_form에서 widgets을 사용해보자.
q_form을 수정해준다.
<form method="post">
{% csrf_token %}
<!-- form에서 widgets사용시
{{ form.as_p }}
-->
{% if form.errors %}
<div class="alert alert-danger" role="alert">
{% for field in form %}
{% if field.errors %}
<div>
<strong>{{ field.label }}</strong>
{{ field.errors }}
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
<div class="mb-3">
<label for="subject" class="form-label">제목</label>
<input type="text" class="form-control" name="subject" id="subject"
value="{{ form.subject.value|default_if_none:'' }}">
</div>
<div class="mb-3">
<label for="content" class="form-label">내용</label>
<textarea class="form-control" name="content" id="content" rows="10">
{{ form.content.value|default_if_none:'' }}
</textarea>
</div>
forms.py 의 widgets 영역은 주석을 걸어준다.
우선 웹에서 http://127.0.0.1:8000/board/ 페이지로 이동해준다.
내용을 입력하지않고 글 작성버튼을 누르면
{% if form.errors %}
<div class="alert alert-danger" role="alert">
{% for field in form %}
{% if field.errors %}
<div>
<strong>{{ field.label }}</strong>
{{ field.errors }}
</div>
{% endif %}
{% endfor %}
</div>
이 코드가 동작하게되어서
제목과 내용을 필수항목으로 입력하라고 요청 alert를 띄워준다.
<div class="mb-3">
<label for="subject" class="form-label">제목</label>
<input type="text" class="form-control" name="subject" id="subject"
value="{{ form.subject.value|default_if_none:'' }}">
</div>
subject 데이터에 값이 없을경우에 none대신 공백을 띄워놔라
value="{{ form.subject.value|default_if_none:'' }}">
만약 제목에 value값을 이렇게 지정해놓는다면
<div class="mb-3">
<label for="subject" class="form-label">제목</label>
<input type="text" class="form-control" name="subject" id="subject"
value="{{ form.subject.value}}">
이렇게 none으로 뜨게되서 매번 none을 지우고 입력해야겠지만
다시 코드를 수정해서 none 값 ' ' blank로 가려주면
value="{{ form.subject.value|default_if_none:'' }}">
사용자가 처음부터 입력할 수 있도록 칸이 비워지게된다.
답변을 등록할 수 있게 코드를 작성해보자.
forms.py파일을 수정하자
AnswerForm 클래스 안에
필수 Meta 클래스를 만들어주고
모델은 Answer로
필드는 content로 받아준뒤
content = 댓글내용으로 수정해준다.
class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
fields= ['contents']
labels = {
'content' : '댓글내용'
}
views.py로가서 c_answer함수를 수정해주자
httpResponseNotAllowed와
AnswerForm을 import시켜준다
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.http import HttpResponse, HttpResponseNotAllowed
from .models import Question
from .forms import QuestionForm
from .forms import AnswerForm
return HttpResponseNotAllowed('Only POST is possible.')
get을 요청하지못하게 만들었다.
q_detail.html을 수정하자.
=> <div class="form-group my-3">
{% endfor %}
<form action="{% url 'board:c_answer' question.id %}" method="POST" class="my-3">
{% csrf_token %}
<div class="form-group my-3">
<label for="content" class="form-label">댓글내용</label>
<textarea name="content" id="content" class="form-control" rows="5"></textarea>
</div>
<div class="d-flex justify-content-end">
<input type="submit" value="댓글작성" class="btn btn-primary">
</div>
</form>
</div>
{% endblock %}
class를 수정해주고
댓글작성버튼을 오른쪽으로 뜨게 수정해준다.
django 테스트
댓글작성폼 수정
q_detail로가서 댓글창이 비워있으면 경고문을 띄울수 있도록 수정해보자
{% endfor %}
<form action="{% url 'board:c_answer' question.id %}" method="POST" class="my-3">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger" role="alert">
{% for field in form %}
{% if field.errors %}
<div>
<strong>{{ field.label }}</strong>
{{ field.errors }}
</div>
{% endif %}
{% endfor %}
</div>
댓글 쪽 for문 안에
조건문을 써서 django 내장객체인 alert경고문으로 경고창을 띄울 수 있도록 바꾸어줬다.
지금은 단일게시판이라고 생각했을때 아무런 문제가 되지않지만
사이트가 확장되면서 그 중의 게시판 하나다 라고 한다면 게시판목록을 띄워야한다.
다음시간에는 부트스트랩 네비게이션바를 사용해서 게시글을 컨트롤 할 수 있게 해보자.
https://getbootstrap.kr/
Bootstrap
강력하고 확장 가능하며 기능이 풍부한 프론트엔드 툴킷. Sass로 빌드 및 커스터마이징하고, 사전 빌드된 그리드 시스템 및 구성 요소를 활용하고, 강력한 JavaScript 플러그인으로 프로젝트에 생기
getbootstrap.kr