Django

Model Relationship (1:N)

zhelddustmq 2024. 8. 19. 20:25

굉장히 흔히 사용되는 관계

1:N 관계 예시

  • 만약 Article에 Author라는 개념을 둔다면,
    • 하나의 Article은 한 명의 Author를 가질 수 있음
    • 한 명의 Author는 여러개의 Article을 가질 수 있음
  • 만약 Article에 Comment라는 개념을 둔다면,
    • 하나의 Article은 여러개의 Comment를 가질 수 있음
    • 하나의 Comment는 하나의 Article을 가질 수 있음

댓글(Comment) 구현

  • articles/models.py
  • models.ForeignKey(<참조하는 모델 클래스>, on_delete=<옵션>)
#articles/models.py

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

    def __str__(self):
        return self.content

on_delete 옵션: https://docs.djangoproject.com/en/4.2/ref/models/fields/#django.db.models.ForeignKey.on_delete

  • CASCADE
    • 부모가 삭제되면 이를 참조하는 객체도 삭제
  • PROTECT
    • 참조하는 객체가 있을경우 예외를 발생시켜 삭제 방지
  • SET_NULL
    • 참조하는 객체가 삭제될 경우 NULL 값으로 지정

외래키 사용하면 장고자 자동으로 _id 붙여줌

# forms.py (1차)

...
class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = "__all__"

 

articles/views.py

# article_detail.html

...
<hr>
<h3>댓글</h3>
<form action="#" method="POST">
    {% csrf_token %}
    {{ comment_form.as_p }}
    <input type="submit" value="댓글작성">
</form>

article은 왜 있냐...?

# forms.py (2차)

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = "__all__"
        exclude = ("article",)

 

로직 구현

# articles/urls.py

path("<int:pk>/comments/", views.comments_create, name="comments_create"),
# articles/views.py

@require_POST
def comment_create(request, pk):
    article = get_object_or_404(Article, pk=pk)
    form = CommentForm(request.POST)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.article = article
        comment.save()
    return redirect("articles:article_detail", article.pk)
  • 역참조 하는 중
  • save(commit=False)
    • 실제 데이터 베이스에 처리되지 않은 상태의 인스턴스를 반환
    • 저장 전, 로직이 필요한 경우에 사용

 

# article_detail.html 변경

<hr>
<h3>댓글</h3>
<form action="{% url "articles:comment_create" article.pk %}" method="POST">
    {% csrf_token %}
    {{ comment_form.as_p }}
    <input type="submit" value="댓글작성">
</form>

 

articles/views.py

# article_detail.html에 추가
# html에서 처리하지 않는 이유는 orderby 등을 처리하고 가져오고 싶기때문

...
<ul>
    {% for comment in comments %}
        <li>
            <p>{{ comment.content }}</p>
        </li>
    {% endfor %}
</ul>

 

댓글 삭제 및 개수 보이기

article_detail.html
views.py
urls.py

 

'Django' 카테고리의 다른 글

Model Relationship(M:N)  (0) 2024.08.21
Custom UserModel(플젝 시작시 유의)  (0) 2024.08.20
Admin  (0) 2024.08.19
Django Static, Media(runserver)  (1) 2024.08.19
회원기능 구현하기  (0) 2024.08.19