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)