댓글기능으로 MTV 연습해보기-2

코변·2022년 5월 27일
1

포스트에 더보기 기능이 가능해졌으니 이제는 더보기 기능에서 댓글을 달고 삭제하는 기능까지 넣어보자!

혹시몰라 남기는 매번 데이터가 옮겨질 때 마다 하는 질문
1. 내가 지금 어딨지?
2. 내가 지금 뭘하는 거지?
3. 어디로 가는거지?

첫번째로 우리가 할 일은 댓글을 db에 저장해야하기 때문에 tweet앱에 새로운 모델을 추가하러 가는 것이다!

  1. 지금 나는 MTV중 MODEL에 와 있다.
  2. 나는 db에 새로운 테이블을 만들기 위해서 새로운 클래스를 만들거다.
  3. 이 클래스(DBtable)은 views.py에서 사용되어 저장을 하거나 저장된 데이터를 불러오는데 쓰인다.

클래스를 만들기에 앞서서 db에 어떤걸 저장해야하는지 클라이언트에 가서 알아와야 한다.

{{ cm.comment }}
{{ cm.author }}
{{ cm.created_at | timesince }}

유저의 댓글을 저장할 comment, 댓글을 쓴 author, 만들어진 시간 created_at 이렇게 세가지 데이터가 필요하다.

class TweetComment(models.Model):
    class Meta:
        db_table = 'comment' 
        
    author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    tweet = models.ForeignKey(TweetModel, on_delete=models.CASCADE)
    comment = models.CharField(max_length=500, default='')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

다음과 같이 클래스를 선언하면 장고의 내장함수의 도움을 받아 외래키 설정과 날짜설정(자동업데이트까지)을 위와 같이 해줄 수 있다. 이제 클래스를 토대로 db를 업데이트해보자.

python manage.py makemigrations
python manage.py migrate

터미널에 다음 명령어를 실행하면 db에 여러 문구들과 함께 업데이트가 완료된다!

이제 이 데이터를 views에 붙이러 가보자

  1. 나는 지금 MTV 중 View에 있다.
  2. 만든 모델 클래스를 활용해서 데이터를 저장하는 함수와 지우는 함수를 만들어보려고 한다.
  3. 이 함수는 urls.py와 path로 연결될 것이다.
from .models import TweetModel,TweetCommentModel

다음과 같이 내가 만든 TweetCommentModel을 views.py에서 사용할 수 있도록 불러와주고

@login_required
def write_comment(request, id):
    this_tweet = TweetModel.objects.get(id = id)
    new_comment = TweetCommentModel()
    new_comment.comment = request.POST.get('comment')
    new_comment.author = request.user
    new_comment.tweet = this_tweet
    new_comment.save()
    return redirect('/tweet/'+str(id))

models 클래스에 내장된 save함수를 통해서 comment에 필요한 값들을 db에 저장한다.

@login_required
def delete_comment(request,id):
    my_comment = TweetCommentModel.objects.get(id=id)
    tweet_id = my_comment.tweet.id
    my_comment.delete()
    return redirect('/tweet/' + str(tweet_id))

comment의 id값을 가져와서 코멘트를 지워주는 함수 (여기서 comment의 id값이라는 부분이 중요하다) 마찬가지로 클래스에 이미 있는 delete함수를 활용하여 데이터를 지워준다.

이제 함수를 모두 작성했으니 urls.py로 가서 마무리작업을 하자.

  1. 프론트와 views.py를 연결해주는 urls.py다.
  2. 지금까지 만든 write_comment와 delete_comment함수를 프론트와 연결해주기 위해서 urls.py에 path로 묶어준다.
  3. 내가 작성한 함수들이 url주소로 묶여 프론트에 가거나 혹은 프론트에서 온 request가 내가 작성한 함수로 갈 수 있게 돕는다.
urlpatterns = [
    path('', views.home, name='home'),
    path('tweet/', views.tweet, name='tweet'),
    path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),
    path('tweet/<int:id>', views.tweet_detail, name='tweet-detail'),
    path('tweet/comment/<int:id>', views.write_comment, name='write-tweet'),
    path('tweet/comment/delete/<int:id>', views.delete_comment, name='delete-comment')
]

이제 주소 명시도 했고 프론트 작업은 받아온 작업물로 완료했으니 이제 실행이 되는지만 보면 될 것 같다.

잉? 왜 아무것도 안나오지? 터미널에도 따로 이슈가 없었고 db에도 문제가 없이 저장이 된다.

혼자 여기저기 뻘짓을 하다보니 views.py에서 디테일 화면을 불러오는 함수인 tweet_detail에 comment정보를 보내주지 않았다.

@login_required
def tweet_detail(request, id):
    my_tweet = TweetModel.objects.get(id=id)
    return render(request, 'tweet/tweet_detail.html', {'tweet' : my_tweet})

DB에 저장을 하고 저 페이지로 리다이렉트를 아무리 해봐야 정보를 주지 않기 때문에 comment 정보가 생기거나 업데이트 되지 않는다.

@login_required
def tweet_detail(request, id):
    my_tweet = TweetModel.objects.get(id=id)
    my_comment = TweetCommentModel.objects.filter(tweet_id = id).order_by('-created_at')
    return render(request, 'tweet/tweet_detail.html', {'tweet' : my_tweet, 'comment':my_comment})

최종적으로 다음과 같이 코드를 고쳐주었고 화면에 댓글도 잘 나오고 잘 지워지는 것을 확인했다.

아 재밌었는데 확실히 공부한걸 문서화하는건 참 힘들다. 이렇게 정리해두면 나중에 도움이 되겠지.

이 글은 1편에서 이어지는 글이므로 못 보신 분을 위해 링크 첨부하겠습니다.

1편보기

profile
내 것인 줄 알았으나 받은 모든 것이 선물이었다.

0개의 댓글