[Django] Database & Migrations

rang-dev·2020년 6월 7일
0

Corey Schafer의 Django Tutorial 실습하면서 기록하기


Database

Django에서는 ORM을 사용하므로 테이블을 생성할때 직접 SQL구문을 쓸 필요가 없다.(ORM은 Flaks에서도 등장했던 개념!)

model을 만들어줘야하기 때문에 models.py로 이동한다!

  • blog/models.py

models 파일에 model을 다 생성했다면 이 변경사항(테이블 생성)을 db에 반영하기위해 migration을 한다.

실행된 SQL을 직접 보고 싶다면 python manage.py sqlmigrate [APP_NAME] [MIGRATION_NUMBER]을 쳐보면 된다. 방금 0001 migration을 실행했으니 python manage.py sqlmigrate blog 0001을 실행해보자.

shell

python manage.py shell을 사용하면 django의 objects를 이용할 수 있고 또한 python code의 실행 결과도 볼 수 있다.

>>> from blog.models import Post
>>> from django.contrib.auth.models import User

이미 만들어둔 두 모델들을 import 한다.

# user의 모든 objects 보기
>>> User.objects.all()
<QuerySet [<User: hyunlang>, <User: TestUser>]>

# 첫번째 object 보기
>>> User.objects.first()
<User: hyunlang>

# 마지막 object 보기
>>> User.objects.last()
<User: TestUser>

# filter 사용: user name이 hyunlang인 object 보기
# 같은 user name이 여러개 있으면 여러개 나올 수 있음
>>> User.objects.filter(username='hyunlang')
<QuerySet [<User: hyunlang>]>

# 여러개 나온다면 first()로 맨 처음 있는 object 확인
>>> User.objects.filter(username='hyunlang').first()
<User: hyunlang>

# 결과값을 user로 할당하기
>>> user = User.objects.filter(username='hyunlang').first()
>>> user
<User: hyunlang>

# user의 id 확인하기
>>> user.id
1
# Primary Key 확인
>>> user.pk
1

# id=1인 사용자를 user에 할당하기
>>> user = User.objects.get(id=1)
>>> user
<User: hyunlang>

## 새 포스트 생성하기
# 모든 Post 확인하기
>>> Post.objects.all()
<QuerySet []>
# 새 포스트 생성하기
>>> post_1 = Post(title='Blog 1', content='First Post Content!', author=user)
# 새 포스트를 생성한게 db에 반영되었나 확인했더니 아직 반영되지않음
>>> Post.objects.all()
<QuerySet []>
# save를 해줘야 반영됨!
>>> post_1.save()
# 모든 post 확인하기
>>> Post.objects.all()
<QuerySet [<Post: Post object (1)>]>

마지막 결과에서 <QuerySet [<Post: Post object (1)>]>이 나오기때문에 어떤 post인지 확인하기가 어렵다. post가 더 descriptive하게 보여질 수 있도록 수정해보자.

models.py의 Post class에서 __str__메소드를 사용하면 된다.

def __str__(self):
	return self.title

변경된 것을 확인해보자. shell을 exit()한 후 다시 접속해야한다.

# 다시 import
>>> from django.contrib.auth.models import User
>>> from blog.models import Post

# 변경사항이 잘 반영되었다.
>>> Post.objects.all()
<QuerySet [<Post: Blog 1>]>

# username이 hyunlang인 사용자를 user에 할당한다.
>>> user = User.objects.filter(username='hyunlang').first()
>>> user
<User: hyunlang>

# 두번째 포스트 생성하기
>>> post_2 = Post(title='Blog 2', content='Sencond Post Content!', author_id=user.id)
>>> post_2.save()
>>> Post.objects.all()
<QuerySet [<Post: Blog 1>, <Post: Blog 2>]>

# 변수에 결과를 할당해서 .을 덧붙여 세부적인 정보도 확인할 수 있다.
>>> post = Post.objects.first()
>>> post.content
'First Post Content!'
# default로 설정해두었기 때문에 직접 지정하지 않으면 생성될 떄의 시간으로 설정되도록 하였다.
# 확인해보자
>>> post.date_posted
datetime.datetime(2020, 6, 7, 6, 23, 53, 427118, tzinfo=<UTC>)
# post의 작성자 확인
>>> post.author
<User: hyunlang>
# post의 email 확인
>>> post.author.email
'hyunlang@email.com'

# user(hyunlang)이 작성한 모든 post들을 나타낸다.
# .post_set만하면 알아볼 수 있는 결과가 나오지 않는다.
>>> user.post_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x7f011c03c370>
# 결과를 확인하려면 .post_set.all()을 써야한다.
>>> user.post_set.all()
<QuerySet [<Post: Blog 1>, <Post: Blog 2>]>

# post_set을 이용하여 특정 작성자의 post를 추가할 수 있다.(이 부분 진짜 신기했다!)
# 여기서는 create로 생성했기 때문에 save가 따로 필요없다.
>>> user.post_set.create(title='Blog 3', content='Third Post Content!')
<Post: Blog 3>
>>> Post.objects.all()
<QuerySet [<Post: Blog 1>, <Post: Blog 2>, <Post: Blog 3>]>

이제 db에 생성한 내용들이 화면에 잘 표현되게끔 설정해보자.

  • blog/views.py 수정

하드코딩했던 posts 딕셔너리 리스트를 지우고 post.objects.all()를 context 딕셔너리에 있는 posts의 value에 넣어준다. 즉, db에 있는 데이터를 보내줄 수 있게 되었다.

  • 브라우저 확인하기

  • 날짜 포맷형식 바꿔주기

이전에는 날짜에 아무런 formatting도 해주지 않은 상태였다. formatting은 home.html에서 다음과 같이 |를 추가하고 formatting code를 사용해서 설정한다. Formatting code는 외우지말고 필요할때마다 구글링해서 찾아보자.

  • 결과확인

Admin Page 설정

GUI인 admin 페이지에 들어가면 user의 생성, 수정, 삭제가 가능한 것을 확인했었다. 이제 post도 여기서 관리할 수 있도록 하려면 어떻게 해야할까?

  • blog/admin.py에 Post 추가해주기

  • admin page 확인

post항목이 생겼다. 클릭해보면 생성되어있는 post들을 확인할 수 있다.

또한 각각의 post 추가, 수정, 삭제 가능하고 author 또한 수정할 수 있다.

profile
지금 있는 곳에서, 내가 가진 것으로, 할 수 있는 일을 하기 🐢

0개의 댓글