[Django] 댓글 생성

Jin·2021년 10월 20일
0

django

목록 보기
13/14
post-thumbnail
post-custom-banner

1. Comment Create

Comment 모델 생성

from django.db import models
from django.db.models.deletion import CASCADE
from django.db.models.fields import DateTimeField

# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=10)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title


class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=CASCADE)
    content = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.content

def comments_create(request, pk):
    article = get_object_or_404(Article, pk=pk)
    comment_form = CommentForm(request.POST)

    if comment_form.is_valid():
        comment = comment_form.save(commit=False)   # commit=False를 하면 db에 저장이 안됨. instance만 생성
        comment.article = article
        comment.save()
    return redirect('articles:detail', article.pk )
  • (commit=False)를 하면 instance는 생성되지만 db에는 저장이 안된다

1. Foreign Key

  • 외부 키
  • 관계형 데이터베이스에서 한테이블의 필드 중 다른 테이블의 행을 식별할 수 있는 키
  • 참조하는 테이블에서 1개의 키(속성or 속성의 집합)에 해당하고 이는 참조되는 측 테이블의 기본 키(Primary Key)를 가리킴
  • 참조하는 테이블의 행 1개 값은, 참조되는 측 테이블의 행 값에 대응됨
  • 참조하는 테이블의 행 여러 개가, 참조되는 테이블의 동일한 행을 참조 할 수 있다.

1) Foreign Key 특징

  • 키를 사용하며 부모 테이블의 유일한 값을 참조 (참조 무결성)
  • 외래 키의 값이 반드시 부모 테이블의 기본 키 일 필요는 없지만 유일한 값이어야 함
  • 참고 : 참조 무결성
    • 데이터베이스 관계 모델에서 관련된 2개의 테이블 간의 일관성을 말함
    • 외래키가 선언된 테이블의 외래 키 속성(열)값은 그 테이블의 부모가 되는 테이블의 기본 키 값으로 존재해야함

2) ForeignKey Field

  • A many to one relationship
  • 2개의 위치 인자가 반드시 필요
    • 참조하는 model class
    • on_delete 옵션

1) 데이터베이스의 Foregin KeyField표현

  • 만약 ForeignKey 인스턴스를 abcd로 생성 했다면 abcd_id로 만들어짐

  • 하지만 명시적인 모델 관계 파악을 위해 참조하는 클래스 이름의 소문자(단수형)로 작성하는 것이 바람직 하다 (1:N)

    2) on_delete

    • 외래 키가 참조하는 객체가 사라졌을 때 외래 키를 가진 객체를 어떻게 처리할 지를 정의
    • 데이터 무결성을 위해서 매우 중요한 설정
    • On_delete 옵션에 사용 가능한 값들
      • CASCADE : 부모 객체가 삭제 됐을 때 이를 참조하는 객체도 삭제 (게시글이 삭제 되면 해당 게시글에 달려있던 댓글들도 다 삭제됨)
      • PROTET : 부모를 삭제 할 때, 참조 되는 객체가 하나라도 있으면 부모 삭제 불가(댓글을 다 삭제하고 나서 게시글 삭제 가능)
      • SET_NULL : Foregin Key를 Null로 바꿔줌
      • SET_DEFAULT : 부모가 삭제 되면 FK에 디포트 값을 넣어줌
      • SET :
      • DO_NOTHING : 아무것도 안함
      • RESTRICT : 참조하는 테이블만 PROTECT처럼 동작을 하고 나머지는 일반적으로 삭제 가능


1:N 관계 realted manager

  • 역참조('comment set')
    • Article(1) -> Comment(N)
    • article.commet 형태로 사용할 수 없고, article.comment_set_manager가 생성 됨 (comment 모델이기 때문에)
    • 게시글에 몇 개의 댓글이 작성 되었는지 Django ORM이 보장할 수 없기에
      • articlecomment가 있을수도 있고, 없을수도 있음
        * 실제로 Article 클래스에는 Comment 외의 어떠한 관계도 작성되어 있지 않음
  • 참조('article')
    • Comment(N) -> Article(1)
    • 댓글의 경우 어떠한 댓글이든 반드시 자신이 참조하고 있는 게시글이 있으므로, comment.article과 같이 접근 가능
    • 실제 ForeignKeyField 또한 Comment 클래스에서 작성됨

2. Comment READ

댓글 출력

  • 특정 article에 있는 모든 댓글을 가져온 후 context에 추가
# articles/views.py

from .models import Article, Comment

def detail(request,pk):
    article = get_object_or_404(Article, pk=pk)
    comment_form = CommentForm()
    comments = article.comment_set.all()
    context = {
    	'article' : article,
        'comment_form' : comment_form,
        'comments' : comments,
    }
    return render(request, 'articles/detial.html', context)

3. Commnet DELETE

댓글 삭제

# articles/urls.py
urlpatterns = [
   path('<int:article_pk>/comments/<int:comment_pk>/detail/', 
	views.comments_delete, name='comments_delete'),
    ]



# articles/views.py

@required_POST
def comments_delete(request, article_pk, comment_pk):
    if request.user.is_authenticated:	# 인증된 사용자만 삭제 가능
      comment = get_object_or_404(Comment, pk=comment_pk)
      comment.delete()
    return redirect('articles:detail', article_pk)
    
        
profile
내가 다시 볼려고 작성하는 블로그
post-custom-banner

0개의 댓글