로딩 중이에요... 🐣
[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
17 댓글 생성 기능 (Form 기반 + API) | ✅ 편저: 코담 운영자
17강 - 댓글 생성 기능 (Form 기반 + API)
댓글 생성 - django form, api 개발✨ 이번 강의 목표
- Django Form 기반 댓글 입력 처리
- Ajax 기반 댓글 생성 API 연동
- Form 유효성 검사 + 커스텀 오류 메시지
1. 댓글 Form 정의 (forms.py)
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['contents']
labels = {"contents": ""}
widgets = {
"contents": forms.Textarea(attrs={
"placeholder": "댓글을 입력하세요...",
"rows": 3,
}),
}
def clean_contents(self):
contents = self.cleaned_data.get("contents", "").strip()
if not contents:
raise forms.ValidationError("댓글 내용을 입력해주세요.")
if len(contents) < 2:
raise forms.ValidationError("댓글은 최소 2자 이상 입력해야 합니다.")
if len(contents) > 100:
raise forms.ValidationError("댓글은 100자 이하로 입력해야 합니다.")
return contents
- 유효성 검사 커스텀(
clean_contents
)으로 강력한 입력 제어 가능 strip()
처리로 공백만 입력하는 경우 방지
2. 댓글 저장 뷰 함수 (views.py)
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from .forms import CommentForm
from .models import Post
from .api import serializers
from django_instagram.utils import form_errors_to_string
@require_POST
@login_required
def comment_create(request, post_id):
if not request.user.is_authenticated:
return JsonResponse({"success": False, "message": "로그인이 필요합니다."}, status=401)
post = get_object_or_404(Post, pk=post_id)
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.author = request.user
comment.post = post
comment.save()
return JsonResponse({"success": True, "comment": serializers.CommentSerializer(comment).data})
return JsonResponse({
"success": False,
"message": "댓글 등록 실패",
"errors": form_errors_to_string(form)
}, status=400)
3. URL 설정 (posts/urls.py)
path('<int:post_id>/comment_create/', views.comment_create, name='comment_create'),
post_id
를 URL에 포함해 해당 포스트에 댓글 연결- RESTful하게 구성 (명확하고 유지보수 편리)
4. 템플릿 index.html 내 폼 예시
<form method="POST" class="comment-form">
<textarea name="contents" rows="3" placeholder="댓글을 입력하세요..."></textarea>
<input type="submit" value="댓글 등록" class="bg-blue-500 text-white px-2 py-1 rounded">
</form>
실제 동작은 JS에서
fetch()
요청을 통해 처리되며 이 폼은 Ajax 전송 대상
5. 유틸 함수 (utils.py)
def form_errors_to_string(form):
"""
Django Form의 errors를 하나의 문자열로 변환하는 함수.
"""
return ", ".join([msg for msgs in form.errors.values() for msg in msgs])
- 유효성 실패 시, 여러 메시지를 하나의 문자열로 만들어서 alert에 표시
6. JS 파일: 댓글 등록 (loadMorePosts.js)
async function commentCreate(postId, csrfToken, event) {
event.preventDefault();
const form = event.currentTarget.closest('form');
const contents = form.querySelector('textarea[name="contents"]').value.trim();
if (!contents) {
alert("댓글을 입력하세요.");
return;
}
try {
const response = await fetch(`/posts/${postId}/comment_create/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrfToken,
},
body: new URLSearchParams({ contents }),
});
const data = await response.json();
if (data.success) {
const articleElement = document.querySelector(`#article-${postId}`);
const commentListElement = articleElement.querySelector('.comment-list');
commentListElement.insertAdjacentHTML(
'afterbegin',
commentListElement(data.comment, csrfToken, data.comment.author.username)
);
form.reset();
} else if (data.errors) {
alert(data.errors);
}
} catch (error) {
console.error('댓글 등록 중 오류 발생:', error);
alert('댓글 등록에 실패했습니다.');
}
}
✅ 정리
- Form → Ajax → View → 저장 → JsonResponse 구조로 처리
CommentForm
에서 유효성 검증으로 클린한 입력 보장- JS에서 댓글 등록 후 실시간 렌더링까지 구현 가능
- 다음 강의에서는 댓글 삭제 및 좋아요 기능을 추가합니다