컴굥일지
[Django Study 12] Commentapp Implementation 본문
반응형
[Mixin 소개 및 Commentapp 구현]
- CreateView는 object가 없고, DetailView는 form이 없다.
- DetailView를 사용하고 싶은데 form과 같이 사용하고 싶다면 Mixin을 사용한다.
Comment
- create, delete만 구현한다.
- 댓글 추가/삭제 이후, 다시 그 게시글로 되돌아가도록 한다.
Comment app 생성
터미널에 python manage.py startapp commentapp을 입력하여 앱 생성
settings.py파일에 가서 INSTALLED_APPS에 가서 ‘commentapp’ 추가
pragmatic/urls.py에 가서 아래 코드를 작성하여 프로필 페이지로 연결해주는 경로를 생성
path('comments/', include('commentapp.urls')),
models.py에서 아래 코드를 작성한다.
from django.contrib.auth.models import User from django.db import models # Create your models here. from articleapp.models import Article class Comment(models.Model): article = models.ForeignKey(Article, on_delete=models.SET_NULL, null=True, related_name='comment') writer = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='comment') content = models.TextField(null=False) created_at = models.DateTimeField(auto_now=True)
forms.py를 작성한다.
from django.forms import ModelForm from commentapp.models import Comment class CommentCreationForm(ModelForm): class Meta: model = Comment fields = ['content']
model을 만들었으니 python manage.py makemigrations와 python manage.py migrate를 터미널에 입력한다.
views.py를 만든다.
class CommentCreateView(CreateView): model = Comment form_class = CommentCreationForm template_name = 'commentapp/create.html' #10번까지 하면 form을 쓸 수 있으므로, 아래와 같은 설정 필요 def form_valid(self, form): temp_comment = form.save(commit=False) temp_comment.article = Article.objects.get(pk=self.request.POST['article_pk']) temp_comment.writer = self.request.user temp_comment.save() return super().form_valid(form) def get_success_url(self): return reverse('articleapp:detail', kwargs={'pk': self.object.article.pk})
commentapp파일로 가서 urls.py 만들고, app_name 설정한다.
from django.urls import path from commentapp.views import CommentCreateView app_name='commentapp' urlpatterns = [ path('create/', CommentCreateView.as_view(), name='create'), ]
- create.html을 만든다.
- articleapp의 create.html과 유사 하나, article에 대한 pk도 서버 단에서 확인하기 위해 form 마지막에 hidden 인풋을 하나 만들어둔다.
- 이렇게 만든 create.html을 articleapp/detail.html에서 include 구문으로 불러오게 한다.
articleapp/views.py에서 mixin을 추가해줘야 한다.
class ArticleDetailView(DetailView, FormMixin): #FormMixin을 추가하고 model = Article form_class = CommentCreationForm #form을 불러온다. context_object_name = 'target_article' template_name = 'articleapp/detail.html'
<!-- value의 article.pk는 articleapp/detail.html로 부터 article정보를 받아온다. -->
<input type="hidden" name="article_pk" value="{{ article.pk }}">
[Commentapp 마무리]
articleapp/detail.html에서 코멘트를 for문으로 보여주기
{% for comment in target_article.comment.all %} {% include 'commentapp/detail.html' with comment=comment %} {% endfor %}
detail.html 만들기. 1번에서 include하게 된다.
<div style="border: 1px solid; text-align: left; padding: 4%; margin: 1rem 0; border-radius: 1rem; border-color: #bbb;"> <div> <strong> {{ comment.writer.profile.nickname }} </strong>     {{ comment.created_at }} </div> <div style="margin: 1rem 0;"> {{ comment.content }} </div> {% if comment.writer == user %} <div style="text-align: right"> <a href="{% url 'commentapp:delete' pk=comment.pk %}" class="btn btn-danger rounded-pill"> Delete </a> </div> {% endif %} </div>
decorators.py 만들기
from django.http import HttpResponseForbidden from commentapp.models import Comment def comment_ownership_required(func): def decorated(request, *args, **kwargs): comment = Comment.objects.get(pk=kwargs['pk']) if not comment.writer == request.user: return HttpResponseForbidden() return func(request, *args, **kwargs) return decorated
DeleteView 만들기
@method_decorator(comment_ownership_required, 'get') @method_decorator(comment_ownership_required, 'post') class CommentDeleteView(DeleteView): model = Comment context_object_name = 'target_comment' template_name = 'commentapp/delete.html' def get_success_url(self): return reverse('articleapp:detail', kwargs={'pk': self.object.article.pk})
delete.html 만들기
{% extends 'base.html' %} {% block content %} <div style="text-align: center; max-width: 500px; margin: 4rem auto"> <div class="mb-4"> <h4>Delete Comment : {{ target_comment.content }}</h4> </div> <form action="{% url 'commentapp:delete' pk=target_comment.pk %}" method="post"> {% csrf_token %} <input type="submit" class="btn btn-danger rounded-pill col-6 mt-3"> </form> </div> {% endblock %}
urls.py 수정하기
urlpatterns = [ path('create/', CommentCreateView.as_view(), name='create'), path('delete/<int:pk>', CommentDeleteView.as_view(), name='delete'), ]
[출처] 작정하고 장고! Django Pinterest 따라만들기 : 바닥부터 배포까지
섹션 5. Commentapp Implementation (37강 ~ 38강)
반응형
'프로그래밍 강의 > Django' 카테고리의 다른 글
[Django Study 14] Projectapp Implementation (0) | 2022.05.13 |
---|---|
[Django Study 13] Mobile Responsive Layout (0) | 2022.05.08 |
[Django Study 11] Articleapp Implementation (0) | 2022.04.26 |
[Django Study 10] Profileapp Implementation (0) | 2022.04.25 |
[Django Study 09] Authentication 인증시스템 구현과 Decorator (0) | 2022.04.24 |
Comments