💬 Chapter 06. Django 블로그에 댓글 기능 추가하기
🎯 목표
블로그 상세 페이지에 댓글 기능을 구현하여 사용자와의 양방향 소통 기능을 구축합니다. 모델 정의부터 템플릿 반영, CBV 기반 뷰 구성까지 전반적인 흐름을 따라갑니다.
1️⃣ 댓글 모델 정의하기 (models.py)
✅ 흐름 설명
- Comment 모델을 만들어 Blog 모델과 연결 (ForeignKey)
- TimestampModel을 상속받아 created_at, updated_at 자동 생성
- 작성자(User)도 ForeignKey로 연결
class Comment(TimestampModel):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
content = models.CharField('본문', max_length=255)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return f'{self.blog.title} 댓글'
class Meta:
verbose_name = '댓글'
verbose_name_plural = '댓글 목록'
ordering = ['-created_at', '-id'] # 최신순 정렬
2️⃣ 추상 모델: TimestampModel
✅ 코드 재사용을 위한 부모 클래스 정의 (utils/models.py)
class TimestampModel(models.Model):
created_at = models.DateTimeField('작성일자', auto_now_add=True)
updated_at = models.DateTimeField('수정일자', auto_now=True)
class Meta:
abstract = True
이 클래스를 상속하면 모든 모델에 작성일자/수정일자가 자동 추가됩니다.
3️⃣ 마이그레이션 적용
python manage.py makemigrations
python manage.py migrate
4️⃣ Admin에서 댓글 관리하기 (admin.py)
✅ CommentInline으로 블로그 상세에서 댓글 관리
class CommentInline(admin.TabularInline):
model = Comment
fields = ['content', 'author']
extra = 1
@admin.register(Blog)
class BlogAdmin(admin.ModelAdmin):
inlines = [CommentInline]
admin.site.register(Comment)
5️⃣ 댓글 입력 폼 만들기 (forms.py)
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('content',)
widgets = {
'content': forms.TextInput(attrs={'class': 'form-control'})
}
labels = {
'content': '댓글'
}
6️⃣ 댓글 출력 및 입력 템플릿 구성 (blog_detail.html)
✅ 로그인한 사용자만 댓글 작성 가능
✅ 하단에 댓글 목록 출력 ( 본문과 목록 중간에 넣기)
{% if request.user.is_authenticated %}
<form method="post">
{% csrf_token %}
{{ comment_form.as_p }}
<div class="text-end">
<button class="btn btn-primary">작성</button>
</div>
</form>
{% endif %}
<div>
{% for comment in blog.comment_set.all %}
<div>
{{ comment.content }}
<p class="text-end">
<small>{{ comment.created_at|date:'Y-m-d H:i' }} | {{ comment.author.username }}</small>
</p>
</div>
{% endfor %}
</div>
7️⃣ 댓글 저장 로직 - 기존 BlogDetailView 수정
class BlogDetailView(DetailView):
model = Blog
queryset = Blog.object.all().prefetch_related('comment_set', 'comment_set__author')
template_name = 'blog_detail.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_form'] = CommentForm()
return context
def post(self, *args, **kwargs):
comment_form = CommentForm(self.request.POST)
if not comment_form.is_valid():
self.object = self.get_object()
context = self.get_context_data(object=self.object)
context['comment_form'] = comment_form
return self.render_to_response(context)
if not self.request.user.is_authenticated:
raise Http404
comment = comment_form.save(commit=False)
comment.blog_id = self.kwargs['pk']
comment.author = self.request.user
comment.save()
return HttpResponseRedirect(reverse_lazy('blog:detail', kwargs={'pk': self.kwargs['pk']}))
Models.py 에 댓글 순서 설정
class Meta:
verbose_name = '댓글'
verbose_name_plural = '댓글 목록'
ordering = ('-created_at', '-id')
8️⃣ 별도 View로 댓글 생성하기 (CommentCreateView)
✅ 로그인한 사용자만 접근 가능
✅ DetailView와 역할 분리
class CommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
form_class = CommentForm
def get(self, *args, **kwargs):
raise Http404
def form_valid(self, form):
blog = self.get_blog()
self.object = form.save(commit=False)
self.object.author = self.request.user
self.object.blog = blog
self.object.save()
return HttpResponseRedirect(reverse('blog:detail', kwargs={'pk': blog.pk}))
def get_blog(self):
pk = self.kwargs['blog_pk']
return get_object_or_404(Blog, pk=pk)
9️⃣ URL 연결 (urls.py)
path('comment/create/<int:blog_pk>/', cb_views.CommentCreateView.as_view(), name='comment_create')
9️⃣ .forms.py 에 url 연결
<form method="post" action="{% url 'blog:comment_create' blog.pk %}">
✅ 최종 요약
- Comment 모델과 TimestampModel로 댓글 기본 구조 생성
- CommentForm과 CBV 기반 View 구현으로 입력 처리
- 템플릿에서 인증된 사용자만 댓글 작성 가능하게 설정
- 관리자 페이지에서도 댓글 관리 가능
👉 다음 단계에서는 댓글 수정/삭제 기능을 추가하거나, 비동기(AJAX) 적용으로 확장할 수 있습니다!
'Django' 카테고리의 다른 글
Chapter 7-1 Django 블로그 이미지 업로드 기능 만들기 (0) | 2025.05.11 |
---|---|
Chapter 6-5 댓글 페이지네이션 구현하기 (ListView + Bootstrap) (0) | 2025.05.09 |
Chapter 6-3 댓글 기능 시작하기 - 모델과 관리자 설정 (0) | 2025.05.09 |
Chapter 6-2 Bootstrap 적용으로 블로그 UI 개선하기 (0) | 2025.05.09 |
Chapter 6-1 [블로그] 댓글 기능 만들기 - Static Files 설정과 Bootstrap 적용 (0) | 2025.05.09 |