TIL #49 Self ForeignKey 설정

채록·2021년 2월 9일
1

Python & Django

목록 보기
21/34
post-thumbnail

대댓글 기능

대댓글을 위해서 대댓글 table을 만든다?? 그럼 이제 댓글 한개당 table 한개가 또 추가되는 것이다.. 댓글이 몇개 달릴줄 알고??

때문에 같은 댓글 table 내에서 처리하고자 한다!

대댓글 또한 댓글과 같은 기능을 갖고있다.! 단지 댓글 아래에 속할 뿐! 이를 위해 self Foreignkey를 먹여주고자 한다

parent = models.ForeignKey('self', on_delete=models.CASCADE, related_name=recomment', null=True)

🔥 주의!

  • 대댓글이 없는 댓글도 있으므로 null=True 해준다.
  • related_name 꼭!
  • 댓글이 없어지면 그 아래 대댓글도 없어져야 하므로 models.CASCADE로 설정한다.



models.py & shell 확인 & db 확인


잘못된 경우

id 1번을 보면.. 먼저 1번과 관련있어 보이는 것은 id 11 번이다.
처음에 의도했던 것은
11번 댓글이 1번 댓글의 대댓글로 달리는것 이었다. 다만 shell 에서 값을 새로 생성할때
parent_id에 직접 값을 입력했기 때문에 완전 다른 양상으로 작성된 것이다.


성공

다시 parenet_id라는 것은, 해당 댓글의 parent가 있느냐!! 즉, 그 댓글이 대댓글이냐! 를 알려주는 field 이다. 때문에
parent_id 가 NULL 인것은 댓글이고, parent_id에 id값이 있다면 그 댓글은 parent_id에 해당하는 댓글의 대댓글임을 의미한다.

때문에 다음과 같이 작성한다. (여기서 related_name을 사용해 reverse many to one 으로 접근했다.)

a.recomment.add(Comment.objects.create(comment='야옹', user_id=32, posting_id=1)

그 결과 위 그림에서 처럼 알맞게 instance가 생성되었다!


값 수정,,

table에서 parent_id는 FK 로써 그 자신의 PK(int) 를 값으로 갖는다! 처음엔 단순히 "0을 NULL로 인식하겠지?" 싶어서

>>> a = Comment.objects.get(id=1)
>>> a.parent_id=0
>>> a.save()

했더니 글쎄 ERROR가 나왓다!!!!
ValueError: The database backend does not accept 0 as a value for AutoField.

0을 허용하지 않는다니.. 그럼 빈 문자열로 표시할때 사용한 ''를 사용해 볼까? 싶었다.
GOTCHA! 🌟




생각보다 대댓글 기능구현이 복잡하진 않았다! 하지만.. 이런식이면 댓글과 대댓글이 모두 한 table에 있고, 한 instance가 사라지면 삭제된 id 값은 재사용 되지 않고 계속 새로운 id만 부여받으니까 나중가면 id 값이 엄청.. 높겠다! 내가다루는 id양은 작고 귀여워


이제 로직 짜러 가야지! ..
잘 짜고 멘탈 괜찮으면 추가로 작성하겠슴;; 왔다!




추가 내용


HTTP request 확인


parent_id의 값을 무조건 받지 않고, 없다면 None으로 받기 위해 date['parent_id']가 아닌 data.get('parent_id', None)으로 설정하였다.

끝!

profile
🍎 🍊 🍋 🍏 🍇

2개의 댓글

comment-user-thumbnail
2021년 2월 11일

잘 읽고 갑니다~ >.<

1개의 답글