목표
- 사용자만이 게시글을 작성할 수 있도록 구현한다.
- 모델 관계를 이해한다.
등록된 사용자만이 게시글을 작성할 수 있도록 구현해보자.
사실 이 부분은 게시글을 작성할 수 있는 권한은 등록된 사용자에게 제한을 둔다는 점보다
모델 간에 관계를 맺는다는 점에서 더 큰 의미가 있다.
이전 포스트까지 진행하면서 데이터베이스에는 아래와 같은 테이블들을 가지고 있다.
생각해보면 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 |
댓글