본문 바로가기
Web Programming/django

[Django] 모델 관계 (1)

by 테리는당근을좋아해 2020. 6. 21.

목표

- 사용자만이 게시글을 작성할 수 있도록 구현한다.

- 모델 관계를 이해한다.

 

등록된 사용자만이 게시글을 작성할 수 있도록 구현해보자.

사실 이 부분은 게시글을 작성할 수 있는 권한은 등록된 사용자에게 제한을 둔다는 점보다

모델 간에 관계를 맺는다는 점에서 더 큰 의미가 있다.

 

이전 포스트까지 진행하면서 데이터베이스에는 아래와 같은 테이블들을 가지고 있다.

 

생각해보면 User라는 클래스는 따로 정의해주지 않았다.

하지만, Django는 User라는 모델을 기본적으로 제공하고 accout 앱 내의 views.py에서 

 

from django.contrib.auth.models import User

 

django.contrib.auth.models의 User 클래스를 import해서 사용하였다.

 

Django 프로젝트 생성과 동시에 createsuperuser를 통해 사용자를 등록할 수 있었고,

admin 페이지에서는 models.py에서 정의해주지 않았던 Users가 처음부터 있었던 것을 확인할 수 있다.

 

다시 본론으로 들어가면,

등록된 사용자만이 게시글을 작성하기 위해서는 Post 테이블에 user에 대한 데이터를 담고 있어야한다.

 

그럴려면 Post에는 너무 많은 데이터들을 담아야하고, 또 이러한 방식에 의해 발생하는 데이터 중복으로 각종 이상현상들 마주하게 될 것이다.

 

이미 관계형 데이터베이스에 대해서 알고 있는 사람이라면, 사실 큰 걱정이 없을 것이다.

User 테이블의 기본키를 참조하기만하면 해결될 수 있기 때문이다.

 

이렇게 특정 테이블을 다른 테이블에서 참조할 수 있도록 관계를 맺어보자

User와 Post는 1:n의 관계를 맺게 된다.

사용자 한명이 여러 게시글을 작성할 수 있지만, 일반적인 게시글에서 여러 사용자가 하나의 게시글을 작성할 수 없기 때문이다.

 

일단 admin 페이지에서 등록된 모든 post를 삭제한다.

 

의문점이 생길 수 있다.

 

'참조 무결성 제약조건이라하면 외래키는 참조하는 릴레이션의 기본키 또는 null 값이니까,

현재 만들어진 레코드들은 외래키 값을를 null로 하면 상관없지 않나요?'

 

맞는 말이다.

 

하지만, 등록된 사용자만이 게시글을 작성할 수 있도록 외래키의 null값을 허용하지 않을 것이고, 등록된 사용자 정보가 삭제되었을 때, cascade 옵션을 사용해서 해당 사용자의 게시글도 모두 삭제할 것이다.

 

그리고 blog 앱 내의 models.py에서 Post 클래스에 user라는 멤버를 하나 만들고 외래키로 User 클래스의 기본키를 참조한다.

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    content = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
    
    def __str__(self):
        return self.title

ForiegnKey 내의 User는 참조하는 릴레이션의 이름, on_delete는 삭제 시 옵션(여기서는 cascade로 둠), null은 null값 허용여부이다.

 

model을 수정해주었다면 migration을 하자

 

만약 위와 같은 내용이 터미널 창에 나타난다면 두 가지 해결방법이 있다.

 

1) 1번 옵션을 선택하고 default 값을 선택해준다. User에 들어가야하는 값은 user.id이므로 int값이다.

2) 앱 내의 migrations 디렉토리를 삭제해준다.

 

둘 중 하나의 방법을 했다면 다시 migration을 해주자

 

 

다음은 views.py에서 해당 글이 생성될 때, Post에 User의 기본키를 함께 저장해주어야한다.

def create(request):
    if(request.method == 'POST'):
        post = Post()
        post.title = request.POST['title']
        post.content = request.POST['content']
        post.pub_date = timezone.datetime.now()
        post.user = request.user
        post.save()
        return redirect('/detail/' + str(post.id))
    else:
        return render(request, 'new.html')

'post.user = reqeust.user'를 작성해 post 객체에 POST 요청을 한 user를 저장한다.

 

 

index.html에서 해당 글에 유저의 이름을 함께 나타내준다.

<p>{{post.user.username}}</p>

 

다시 서버를 실행하고 게시글을 작성해보면 해당 게시글의 작성시간 밑에 작성한 사용자의 username이 함께 나타난다.

'Web Programming > django' 카테고리의 다른 글

[Django] 정적파일  (1) 2020.06.21
[Django] 모델 관계 (2)  (0) 2020.06.21
[Django] 회원가입 기능 만들기  (5) 2020.06.20
[Django] CRUD Operation(5)  (2) 2020.06.20
[Django] CRUD Operation(4)  (0) 2020.06.20

댓글