1)
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete = models.CASCADE) # post_id 필드가 생성된다.
message = models.TextField()
post 같은 경우는 post_id 형식으로 필드를 생성하기 위한 가상의 필드라서 실제 db 필드와는 다르다.
2)
comment.post
# Post.objects.get(pk = comment.post_id)
post_id 값을 확인하고 이를 다시 pk에 할당해서, Post 모델의 객체에서 이와 맞는 것을 찾는 방식보다 Comment 모델을 정의할 때 "Post와 관련있어~" 라고 걸고 넘어간 부분을 통해 comment.post(가상의 필드)로 구하는 방법이 더 직관적이고 효율적이다.
3)
Input
comment = Comment.objects.all().first()
comment
Output
<Comment: Comment object (1)>
...
Input
comment.post
Output
<Post: 네 번째 포스팅>
쿼리셋의 select는 Comment에 대해서 한 번, Post에 대해서 한 번, 총 두 번 이뤄진다.
4)
# Comment.objects.filter(post_id = 4)
# Comment.objects.filter(post__id = 4)
# Comment.objects.filter(post = post)
post.comment_set.all()
세 값의 결과는 같은데 특히 post_id = 4는 comment의 직접적인 필드 값 'post_id'를 찾는 경우이고 post__id = 4는 외래키 'post'로 엮인 실제 Post 측의 id 값을 확인하는 경우이다.
1:n 의 관계에서 1 측은 참조할 이름이 없는데 이렇게 '모델명 소문자_set'을 이용해 접근하는 것을 reverse_name이라고 한다.
서로 다른 앱에서 같은 이름의 모델들이 있을 시 충돌이 나므로, 커스터마이징 해줄 것.
5)
from django.conf import settings
...
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete = models.CASCADE)
accounts라는 app을 따로 만들어서 Profile 모델을 내부에 만들어 줄 때 settings의 AUTH_USER_MODEL을 걸고 넘어졌다.
이 Profile의 reverse name을 통해서 User를 얻는 방법이 아래 User 모델을 직접 가져오는 방법보다 더 concrete하다고 하신다. 그나마 get_user_model은 현재 활성화된 유저를 보여주므로 더 선호할만하다.
6)
You have 1 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): auth.
askcompany 프로젝트를 생성하던 강의 초기에 장고 3.0.14 버전을 migrate했다. 모종의 이유로 현재 버전은 4.0.5로 확인되는데 migrate할 파일이 더 많은 게 오류의 원인이다.