Django - Model Extension

nathan·2021년 7월 21일
0

Django

목록 보기
19/22
post-custom-banner

이번엔 게시물에 작성자를 연결해보자.

DB(모델)을 구성할 때는 바로 작성하는 것이 아니라, 구조를 정확히 파악하고 설계를 한 이후에 작성해야한다.

그렇지 않으면 이미 삽입된 내용에 새로운 열을 추가하는 것이므로, 충돌이 일어날 수 있다.


게시물과 작성자의 관계

  • 작성자(유저)는 여러 게시물(Blog)을 작성할 수 있다.
  • 반면 게시물은 1명의 유저에게만 연결될 수 있다.
  • 따라서 1(유저) : N(게시물)의 관계라고 볼 수 있다.

게시물 - 작성자 연결하기

  • 게시물에 연결을 해줘야하니, Blog가 있는 models.py로 가자
    blog/models.py
from django.db import models
from account.models import CustomUser

# Create your models here.
class Blog(models.Model):
    user = models.ForeignKey(CustomUser, null=True, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    writer = models.CharField(max_length=10)
    pub_date = models.DateTimeField()
    body = models.TextField()
    image = models.ImageField(upload_to="blog/", blank=True, null=True)

    def __str__(self):
        return self.title

    def summary(self):
        return self.body[:100]
  • user = models.ForeignKey(CustomUser, null = True, on_delete = model.CASCADE)

    • 1:N 혹은 N:1 관계를 표현한다.
    • 단 N을 담당하는 테이블에 ForeignKey를 설정해야한다.
    • 이렇게 되면 User는 여러 게시물을 쓸 수 있게 된다.
  • 원래는 writer에 user가 들어가지만, 기존 작성 코드와의 충돌을 피하기 위해 새로운 필드를 하나 만들었다.

    • 실제로 실습 진행을 할 땐, 처음부터 writer에 FK로 user를 엮어줘도 된다.
  • on_delete=models.CASCADE

    • cascade : 폭포처럼 물이 떨어지는 것을 의미
    • 프로그래밍에서 cascade는 어떤 하나의 일이 일어날 때, 연쇄작용을 일으키는 것을 의미
    • 여기선 FK를 통해 연결된 객체가 삭제되면 이 객체도 삭제하겠다는 의미
    • 위의 코드에서 연결된 CustomUser 객체가 삭제되면 해당 Blog 객체도 삭제
  • 1:1 관계는 어떻게 설정??

  • 모델을 변경했으면 꼭 makemigrations, migrate를 해주자.


게시물에 User 연결하기

blog/views.py

def create_with_django_form(request):
    form = BlogForm(request.POST, request.FILES)
    if form.is_valid():
        new_blog = form.save(commit=False)
        new_blog.pub_Date = timezone.now()
        if request.user.is_authenticated:
            new_blog.user = request.user
        new_blog.save()
        return redirect('blog:detail', new_blog.id)
    return redirect('home')
  • new_blog.user = request.user : Blog에 있었던 user 필드를 request.user, 즉 현재 로그인 된 User 객체로 연결한다.

blog/templates/detail.html

{% extends 'base.html' %}
  {% block content %}
      <h1>{{ blog.title }}</h1>
      <p>유저: {{blog.user.username}}</p>
      <p>{{ blog.pub_date }}</p>
      <p>{{ blog.body }}</p>
        {% if blog.image %}
        <img src="{{blog.image.url}}" alt="" />
        {% endif %}
      <a href="{% url 'blog:update' blog.id %}">수정하기</a>
      <a href="{% url 'home' %}">돌아가기</a>
      <a href="{% url 'blog:delete' blog.id%}">Delete Post</a>
  {% endblock %}
  • 변수이름.user.username : 연결된 테이블의 값을 접근하는 방법은 똑같다.
      1. 변수이름 : views에서 받은 Blog 객체
      1. 변수이름.user : Blog 객체의 user 필드 -> User 객체가 담겨있음
      1. 변수이름.user.username : username을 접근할 수 있다.

마무리

  • 응용을 더 해보면, 다음과 같은 기능을 추가할 수 있다.
    • 로그인을 하지 않은 유저가 작성한 글에 대해선 username 대신 다른 텍스트(ex: '익명', '게스트' 등)를 보여주는 기능
    • 로그인을 하지 않은 유저는 글쓰기를 하지 못하게 만드는 기능
      • 로그인 안되어있으면, 그냥 글쓰기 버튼 없애기

도전해보기

  • 게시물 - 댓글 관계 생각해보기
  • 어느 관계인지 생각해보고 직접 구현해보기

누가 작성했는지
어느 게시물에 작성하는지
무슨 내용인지

  • 위의 3가지 내용이 들어간다.
profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.
post-custom-banner

0개의 댓글