데이터 분석 기술 블로그

DB에 대하여(5)_댓글 CREATE (feat. Django) 본문

DB

DB에 대하여(5)_댓글 CREATE (feat. Django)

데이터분석가 이채은 2024. 4. 20. 09:00

1. 사용자로부터 댓글 데이터를 입력받기 위한  CommentForm 정의

# articles/forms.py

from .models import Article, Comment


class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = '__all__'

2. deatil view 함수에서 CommentForm을 사용하여 detail 페이지에 렌더링

# articles/views.py

from .forms import ArticleForm, CommentForm


def detail(request, pk):
    article = Article.objects.get(pk=pk)
    comment_form = CommentForm()
    context = {
        'article': article,
        'comment_form': comment_form,
    }
    return render(request, 'articles/detail.html', context)
<!-- articles/detail.html -->

<form action="#" method="POST">
  {% csrf_token %}
  {{ comment_form }}
  <input type="submit">
</form>

3. CommentForm의 출력 필드 조정

Comment 클래스의 외래 키 필드 article 또한 데이터 입력이 필요한 필드이기 때문에 출력되고 있습니다. 하지만, 외래 키 필드는 사용자 입력 값으로 받는 것이 아닌 view 함수 내에서 다른 방법으로 전달받아 저장되어야 합니다.

# articles/forms.py

from .models import Article, Comment


class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('content',)

4. url 작성 및 action 값 작성

출력에서 제외된 외래 키 데이터는 어디서 받아와야 할까요?

detail 페이지의 url인 path('<int:pk>/', views.detail, name='detail')에서 해당 게시글의 pk 값이 사용되고 있습니다.

댓글의 외래 키 데이터에 필요한 정보가 바로 게시글의 pk값입니다.

# artciels/urls.py

urlpatterns = [
    ...,
    path('<int:pk>/comments/', views.comments_create, name='comments_create'),
]
<!-- articles/detail.html -->

<form action="{% url 'articles:comments_create' article.pk %}" method="POST">
  {% csrf_token %}
  {{ comment_form }}
  <input type="submit">
</form>

5. comments_create view 함수 정의

artciel 객체는 언제 저장할 수 있을까요?

# articles/views.py

def comments_create(request, pk):
    article = Article.objects.get(pk=pk)
    comment_form = CommentForm(request.POST)
    if comment_form.is_valid():
        comment_form.save()
        return redirect('articles:detail', article.pk)
   context = {
       'article': article,
       'comment_form': comment_form,
   }
   return render(request, 'articles/detail.html', context)

6. save의 commit 인자를 활용해 외래 키 데이터 추가 입력

save(commt=False)는 DB에 저장하지 않고 인스턴스만 반환합니다.

# articles/views.py

def comments_create(request, pk):
    article = Article.objects.get(pk=pk)
    comment_form = CommentForm(request.POST)
    if comment_form.is_valid():
        comment = comment_form.save(commit=False)
        comment.article = article
        comment_form.save()
        return redirect('articles:detail', article.pk)
   context = {
       'article': article,
       'comment_form': comment_form,
   }
   return render(request, 'articles/detail.html', context)

댓글 작성 후 테이블 확인