ACHO.pk devlog

[멋쟁이사저처럼10기] Django 개발자 대나무숲 프로젝트(댓글 구현하기) 본문

멋쟁이사자처럼

[멋쟁이사저처럼10기] Django 개발자 대나무숲 프로젝트(댓글 구현하기)

Acho 2022. 7. 9. 20:07

https://acho.tistory.com/46 와 이어지는 글입니다.


게시글에 댓글 구현

 

snsapp/models.py

  • 우리가 정의하고자 하는 Table를 Class 형태로 정의해줘야한다.
  • ORM : Class를 이용해서 데이터 베이스에 매핑하는 Model
  • Post에 종속적인게 댓글이기 때문에 댓글이 어떤 Post에 달려있는지 알려주는 ForeignKey를 써야한다.
  • on_delete=models.CASCADE  : 댓글이 달린 Post가 삭제되면 참조하고 있는 Comment 객체도 삭제된다.
class Comment(models.Model):
    comment = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    
    #Post를 참조하는 ForeignKey
    post = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
    
    #admin 페이지에서도 확인 가능
    def __str__(self):
        return self.comment
python manage.py makemigration
python manage.py migrate

 

detail.html

댓글 입력 공간

  • 제출 버튼을 클릭했을 때 new_comment라는 url에서 내가 입력한 댓글이 처리된다.
  • 어떤 게시물에 해당되는 댓글인지 알려주기 위해 post_detail.id도 함께 써줘야한다.
<!-- 댓글 입력 공간 -->
<form method="POST" action="{% url 'new_comment' post_detail.id  %}">
    {% csrf_token %}
    <div class="form-group">
        {{ comment_form }}
    </div>
    <input type="submit" class="btn btn-primary btn-icon-split btn-sm" value="댓글 입력">
</form>

 

forms.py

  • Comment Form을 생성한다. (댓글 입력 창)
class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['comment']

    def __init__(self, *args, **kwargs):
        super(CommentForm, self).__init__(*args, **kwargs)

        self.fields['comment'].widget.attrs = {
            'class': 'form-control',
            'placeholder': "댓글을 입력해주세요",
            'rows': 10
        }

 

views.py

  • detail.html를 띄워주는 함수인 detail 함수에 comment_form 변수에 CommentForm()를 받아와서, comment_form를 두번째 인자로서 넘겨준다.
  • get_object_or_404(Post, pk=post_id) 를 통해 특정 pk 값을 갖는 POST. 즉, 그 게시물에 달려 있는 댓글에 해당하는 게시물의 정보를 담아준다.
 # 게시글 제목 상세 페이지
def detail(request, post_id):
    post_detail = get_object_or_404(Post, pk=post_id)
    comment_form = CommentForm()
    return render(request, 'detail.html', {'post_detail':post_detail, 'comment_form': comment_form})
    
    
 # 댓글 저장
def new_comment(request, post_id):
	#POST로 요청을 보낸 CommentForm을 filled_form 변수에 저장한다.
    filled_form = CommentForm(request.POST)
    
    if filled_form.is_valid():
        finished_form = filled_form.save(commit=False)
        finished_form.post = get_object_or_404(Post, pk=post_id)
        finished_form.save()
    return redirect('detail', post_id)

 

urls.py

urlpatterns = [
path('new_comment/<int:post_id>', views.new_comment, name='new_comment'),
]

 

admin.py

admin 사이트에서 확인할 수 있도록 등록한다.

from .models import Comment

admin.site.register(Comment)

 

detail.html

댓글 목록 공간

  • form을 통해서 각각의 댓글들을 순회한다. 
  • post_detail (게시물)을 참조하고 있는 comment_set(comment의 집합)의 전체(all)를 순회함으로써 하나하나가 comment에 담긴다.
<!-- 댓글 목록 공간 -->
{% for comment in post_detail.comment_set.all %}
{{ comment }}
<hr>
{% endfor %}

Comments