Django - Model Extension
이번엔 게시물에 작성자를 연결해보자.
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
관계는 어떻게 설정??- models.OneToOneField를 사용하면 된다.
- 사용방법은 ForeignKey와 거의 동일
- https://docs.djangoproject.com/en/3.2/topics/db/examples/one_to_one/
-
모델을 변경했으면 꼭
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
: 연결된 테이블의 값을 접근하는 방법은 똑같다.변수이름
: views에서 받은 Blog 객체
변수이름.user
: Blog 객체의 user 필드 -> User 객체가 담겨있음
변수이름.user.username
: username을 접근할 수 있다.
마무리
- 응용을 더 해보면, 다음과 같은 기능을 추가할 수 있다.
- 로그인을 하지 않은 유저가 작성한 글에 대해선 username 대신 다른 텍스트(ex: '익명', '게스트' 등)를 보여주는 기능
- 로그인을 하지 않은 유저는 글쓰기를 하지 못하게 만드는 기능
- 로그인 안되어있으면, 그냥 글쓰기 버튼 없애기
도전해보기
게시물 - 댓글
관계 생각해보기- 어느 관계인지 생각해보고 직접 구현해보기
누가 작성했는지
어느 게시물에 작성하는지
무슨 내용인지
- 위의 3가지 내용이 들어간다.
Author And Source
이 문제에 관하여(Django - Model Extension), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@nathan29849/Django-Model-Extension저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)