코딩 개발일지

장고(Django) 댓글쓰기/지우기 본문

AI 본 교육/AI 6주차

장고(Django) 댓글쓰기/지우기

호기호 2023. 9. 11. 23:19

가장먼저 detail 페이지를 만들어 줄 것이다. (게시글 1개 보기!!!!)

views.py에 detail 함수를 만들어 주고

def detail(request):
    pass

urls.py에서 path로 연결해 준다!

path('<int:bucket_id>/', views.detail),  # 게시물 1개 보기

detail.html도 만들어 준다.

이제 detail 함수를 만져준다. (bucket은 버킷리스트이다ㅋㅋㅋ)

# 개인 게시물 페이지
def detail(request, bucket_id):
    bucket = Bucket.objects.get(id=bucket_id)
    context = {
        'bucket': bucket,
    }
    return render(request, "bucket/detail.html", context)

이러면 기본적인 페이지 완성!


이제 댓글에 대한 models.py 정의해준다. 입맛대로 넣고싶은거 넣어주기!!

bucket과 user는 각각 외래키로 가져옴

class Comment(models.Model):
    bucket = models.ForeignKey(Bucket, on_delete=models.CASCADE)
    user = models.ForeignKey("users.User", on_delete=models.CASCADE)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

migrate 과정을 해주면 데이터베이스에 생성이 된다.

detail과 마찬가지로 views.py에 함수 만들어 준다. csrf랑 login_required는 import해준다.ㅇ

views.py를 작성하는데, bucket_id=bucket_id이부분 때문에 반나절 시간을 썼다..

처음에는 저걸 아예 안넣었는데, bucket_id 쪽에서 에러가 계속났다. (이때는 이게 대체 뭔소리야 이랬음)

이것저것 만져보면서 고쳐봤지만, 다른 오류가 계속 발생했다.

그러다가 데이터베이스의 comment table을 봤는데, 그제서야 bucket_id에 값을 넣을 것을 지정해 줘야 하구나 했음.

근데 문제는 [ bucket_id = ] 뒤에 뭘 넣어야 할지 도저히 모르겠음. 다른것처럼 request.??? 이것밖에 생각이 안났음.

그래서 튜터님께 물어보니 그냥 bucket_id=bucket_id 넣으면 된다고 하심. 하고 나니까 너무 간단해 보여서 슬펐음.

 
# 댓글생성
@login_required(login_url='/users/login/')
@csrf_exempt
def comments_create(request, bucket_id):
    if request.method == "POST":
        Comment.objects.create(
            content=request.POST["content"],
            user=request.user,
            bucket_id=bucket_id
        )
        return redirect(f'/bucket/{bucket_id}/')
    else:
        return HttpResponse('Invalid request method', status=405)

댓글 삭제는 쉬웠다. 좀 생각해야 할 것이라면, 매개변수를 requestbucket_idcomment_id 세개를 쓴다.

comment_id 가 생성되고, 그 comment를 지워야하는거니까 어찌보면 당연한...? (근데 처음 작성할땐 몇시간동안 모름)

이렇게 함수를 정의하면, 매개변수를 urlspy에서도 다 써야한다.(다 안쓰니까 에러나던데 정확하진 않음)

# 댓글삭제
@csrf_exempt
def comments_delete(request, bucket_id, comment_id):
    if request.method == "POST":
        comment = Comment.objects.get(id=comment_id)
        comment.delete()
        return redirect(f'/bucket/{bucket_id}/')
    else:
        return HttpResponse('Invalid request method', status=405)

그래서 urls.py는 이렇게 썼다.

     path('comments_create/<int:bucket_id>/', views.comments_create),  # 댓글쓰기
     path('comments_delete/<int:bucket_id>/<int:comment_id>/', views.comments_delete),  # 댓글삭제

댓글이 생겼으니까, detail도 comments를 추가해준다.

# 개인 게시물 페이지
def detail(requestbucket_id):
    bucket = Bucket.objects.get(id=bucket_id)
    comments = Comment.objects.all()
    context = {
        'bucket'bucket,
        'comments'comments,
    }
    return render(request"bucket/detail.html"context)

이제 detail.html 에서 위 기능들을 다 넣어주면 된다.

<!-------------------------------여기부터 댓글-----------------------------------> (위에 생략하겠음)
    <div>
    댓글 목록 :
    </div>
    <div>
        {% for comment in comments %}

                <li>{{ comment.content }}</li>
                <form action="/bucket/comments_delete/{{bucket.id}}/{{comment.id}}/" method="post">
                    {% csrf_token %}
                    <button type='submit'> 댓글삭제 </button>
                </form>

        {% empty %}
            <p>아직 댓글이 없습니다.</p>
        {% endfor %}
    </div>
    <div>
        <form action='/bucket/comments_create/{{bucket.id}}/' method='post'>
            {% csrf_token %}
            <input type='text' name='content' placeholder='댓글을 입력해주세요'>
            <button type='submit'> 댓글달기 </button>
        </form>
    </div>
</body>
</html>

for 반복문을 써서 댓글들을 보여준다.

반복문 안에 {{ comment.content }}로 댓글들을 보여주고 form으로 삭제기능을 post 해준다.

만약 댓글이 없으면, '아직 댓글이 없습니다.' 가 나온다.

 

댓글달기 또한 form으로 post 해주면 완성!!


하.지.만..!!!

여기서 또 역대급 고뇌에 빠진다. 다른 글에 들어가면, 해당 글에대한 댓글만 나와야하는데, 전체 댓글이 보이는걸 고쳐줘야했다.

아하!!!! html에서 {% if {{bucket.id}} == 어쩌구 %} 이런식으로 게시글 번호 같으면 나오게 해야겠다^^ 라고 생각함

 

근데 생각해보니, 이건 껍데기에 불과한 html 고치기 아닌가?? 데이터베이스쪽을 만져줘야겠는걸? 이라는 생각을 몇시간만에 했음.

 

그러면,,,, views.py의 detail을 고쳐줘야겠군.

comments = Comment.objects.all()

여기서 comment를 전부 다 가져오는게 문제같단 말이지

이걸 어떻게 바꿔야 할까?

bucket table의 pk(id) 랑 comment table의 bucket_id 가 같을 때만 나오면 되잖아. 라는 결론에 다다름.

comments = Comment.objects.get( ????????? )

get으로 뭔가를 가져와야하는데 대체 어떻게 가져오냐고!!!!!!!!!!!!!!!! filter로 bucket_id만 가져올 수 있나? ㄴㄴ

뭔가 if bucket == comment table의 bucket_id :

하면 될것 같은데 도저히 몰라서 튜터님께 도움을 청했다.

 

결론은 '역참조'를 해야했다. (처음들어보는데 어떻게 함??)

역참조에대한 설명과 자세한 공부는 다음 글에...!!