질문 목록 페이지에 질문 등록 버튼을 생성하여 질문을 추가할 수 있는 기능을 추가
templates/pybo/question_list.html에 버튼 추가
...
</table>
<a href="{ url 'pybo:question_create' &}" class="btn btn-primary">
질문 등록하기
</a>
</div>
...
pybo/urls.py에 질문 등록 버튼에 대한 url 매핑 추가
...
urlpatterns = [
...
path('question/create/', views.question_create, name='question_create'),
]
pybo/views.py에 question_create 함수 추가
from .forms import QuestionForm
...
def question_create(request):
# pybo 질문 등록
form = QuestionForm()
return render(request, 'pybo/question_form.html', {'form': form})
pybo/forms.py에 장고 폼 작성
from django import forms
from pybo.models import Question
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ['subject', 'content']
template/pybo/question_form.html에 장고 폼 적용
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h5 class="my-3 border-bottom pb-2">질문 등록</h5>
<form method="post" class="post-form my-3">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">저장하기</button>
</form>
</div>
{% endblock %}
화면 출력 확인
pybo/view.py의 question_create 함수를 수정하여 데이터 저장 기능 추가
...
def question_create(request):
# pybo 질문 등록
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('pybo:index')
else:
# request.method가 GET인 경우
form = QuestionForm()
context = {'form': form}
return render(request, 'pybo/question_form.html', {'form': form}우
질문 등록 확인
질문의 제목과 내용을 입력해 저장
질문 목록에 새로운 질문이 등록된 것을 확인
form에 bootstrap 적용 및 항목 이름을 한글로 수정
{{ form.as_p }} 태그를 사용하면 form에 bootstrap을 사용할 수 없는 문제가 생긴다. 이러한 문제는 forms.py에서 widget 속성을 추가하여 적용할 수 있다.
pybo/forms.py
...
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': '내용',
}
적용 확인
{{ % form.as_p %}} 대신 HTML 코드를 직접 작성해서 form 작성
pybo/form.py에서 widgets 속성 삭제 → {{ % form.as_p %}}에 적용하는 속성이라 이를 사용하지 않으면 필요없기 때문
templates/pybo/question_form.html 수정
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h5 class="my-3 border-bottom pb-2">질문 등록</h5>
<form method="post" class="post-form my-3">
{% csrf_token %}
<!-- 오류 표시 Start -->
{% if form.errors %}
<div class="alert alert-danger" role="alert">
{% for field in form %}
{% if field.errors %}
<strong>{{ field.label }}</strong>
{% endif %}
{% endfor %}
</div>
{% endif %}
<!-- 오류 표시 End -->
<div class="form-group">
<label for="subject">제목</label>
<input type="text" class="form-control" name="subject" id="subject" value="{{ form.subject.value|default_if_none:'' }}">
</div>
<div class="form-group">
<label for="content">내용</label>
<textarea class="form-control" name="content" id="content" rows="10">{{ form.content.value|default_if_none:'' }}</textarea>
</div>
<button type="submit" class="btn btn-primary">저장하기</button>
</form>
</div>
{% endblock %}
오류 확인
pybo/forms.py에 AnswerForm 클래스 추가 및 pybo/views.py의 answer_create 함수 수정
...
from pybo.models import Question, Answer
...
class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
fields = ['content']
labels = {
'content': '답변내용',
}...
from .forms import QuestionForm, AnswerForm
...
def answer_create(request, question_id):
# pybo 답변 등록
question = get_object_or_404(Question, pk=question_id)
if request.method == "POST":
form = AnswerForm(request.POST)
if form.is_valid():
answer = form.save(commit=False)
answer.create_date = timezone.now()
answer.question = question
answer.save()
return redirect('pybo:detail', question_id=question.id)
else:
# request.method가 GET인 경우
form = AnswerForm()
context = {'question': question, 'form':form}
return render(request, 'pybo/question_detail.html', context)질문 상세 템플릿에 오류 영역 추가
...
<!--답변 입력 영역-->
<form action="{% url 'pybo:answer_create' question.id %}" method="post" class="my-3">
{% csrf_token %}
<!-- 오류 표시 영역 Start -->
{% if form.errors %}
<div class="alert alert-danger" role="alert">
{% for field in form %}
{% if field.errors %}
<strong>{{ field.label }}</strong>
{{ field.errors }}
{% endif %}
{% endfor %}
</div>
{% endif %}
<!-- 오류 표시 영역 End -->
...오류 확인