본문 바로가기

Django/Django 기초

[Django] 2 - 2. 모델

이전 포스트

 

[Django] 1. 개발 환경 설정 https://wroni.tistory.com/4

[Django] 2 - 1. URL과 View https://wroni.tistory.com/5


2 - 2. 모델

 

1. 장고 앱 migrate

 

 

python manage.py runserver로 웹 서버를 구동시키면

18개 적용되지 않은 migration들이 있다는 메세지가 뜬다. python manage.py migrate 코드로 migrate를 시키라는 메세지도 뜬다.

 

파일 : C:\projects\mysite\config\settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 

해당 파일을 열면 설치된 앱들을 확인할 수 있다. migration이 필요한 앱들은 데이터베이스가 필요한 앱들이다

 

파일 : C:\projects\mysite\config\settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

 

데이터베이스 엔진이 django.db.bakends.sqlite3라고 정의되어 있는 것을 확인할 수 있다.

 

이제 명령프롬프트에서 migrate를 하자

 

python manage.py migrate

 

admin, auth, contenttypes, sessions 앱들이 사용하는 테이블들이 생성되었다.

 

 

2. DB Browser for SQLite

 

테이블이 만들어지는 걸 확인해보기 위해 SQLite를 설치해서 확인해보자

https://sqlitebrowser.org/dl/

 

Downloads - DB Browser for SQLite

(Please consider sponsoring us on Patreon 😄) Windows Our latest release (3.12.2) for Windows: Windows PortableApp Note - If for any reason the standard Windows release does not work (e.g. gives an error), try a nightly build (below). Nightly builds ofte

sqlitebrowser.org

설치 방법은 따로 변경할 사항 없이 next만 누르면 된다. 설치 후 데이터베이스 열기 -> C:\projects\mysite\db.sqlite3 파일을 선택하자

 

 

이런식으로 구성되어 있는 것을 확인할 수 있다.

 

 

3. 모델 작성

 

데이터 모델을 작성해보자

질문(Question) 모델과 답변(Answer) 모델을 만들 것이다. 각각의 속성들을 알아보자.

 

Question

속성 설명
subject 제목
content 질문 내용
create_date 질문을 작성한 일시

Answer

속성 설명
question 질문
content 답변 내용
create_date 답변을 작성한 일시

 

이제 pybo\modles.py에 질문(Question)과 답변(Answer)에 해당되는 모델을 정의해보자

 

파일 : C:\projects\mysite\pybo

class Question(models.Model):
    subject = models.CharField(max_length=200)
    content = models.TextField()
    create_date = models.DateTimeField()

class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    content = models.TextField()
    create_date = models.DateTimeField()

 

Question 모델

subject는 제목이 최대 200자까지 작성 가능하도록 하였고, content는 글자 수를 제한할 수 없어서 textfield를 사용하였다.

create_date는 날짜와 시간에 관계된 속성이므로 DateTimeField를 사용한다

 

▷ Answer 모델

question은 Question 모델을 속성으로 연결하여 외래키(ForignKey)로 연결하였다. 그리고 질문이 삭제되면 답변도 삭제되도록 on_delete=models.CASCADE를 사용하였다.

 

이제 작성한 모델을 이용하여 테이블을 생성해보자

테이블을 생성하려면 pybo 앱을 config\settings.py 파일의 INSTALLED_APPS 항목에 추가해야 한다

 

파일 : C:\projects\mysite\config\settings.py

INSTALLED_APPS = [
    'pybo.apps.PyboConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

'pybo.apps.PyboConfig',

이는 pybo.apps.PyboConfig 클래스는 pybo\apps.py 파일에 있는 클래스인데, pybo 앱 생성시 자동으로 만들어지는 파일이다.

 

파일 : C:\projects\mysite\pybo\apps.py

 

이제 테이블 생성을 위해 migrate 명령을 수행하자

 

?? No migrations to apply?

manage.py makemigrations 수행 후에 migrate 명령을 수행하라고 한다

 

그렇다면, 하라는대로 makemigrations 명령을 수행하자

 

python manage.py makemigrations

 

makemigrations 명령은 모델을 생성하거나 모델에 변화가 있으면 실행하야 하는 명령이다.

이제 001_initial.py가 생겼다는 문구를 확인할 수 있다. 실제로 생긴 걸 확인할 수 있다.

 

이제 변경사항이 없으므로 makemigrations을 수행하여도 아무 일도 일어나지 않는다.

 

 

makemigrations로 데이터베이스 작업 파일을 생성하고 migrate 명령을 실행하기 전에 어떤 쿼리문이 실행되는지 sqlmigrate 명령으로

확인해보자

 

 

이제 migrate 명령을 수행하고 실제 테이블을 생성해보자

 

 

잘 수행되었다. 이제 DB Browser for SQLite로 질문과 답변에 대한 테이블이 생성되었는지 확인해보자

 

 

잘 생성된 걸 확인할 수 있다.

 

 

4. 모델 사용

장고 셸로 모델 사용법을 알아보자

 

python manage.py shell

 

>>>가 뜨는 걸로 봐서 셸을 사용할 수 있는 상태가 되었다.

 

Question 생성

 

from pybo.models import Question, Answer

from django.utils import timezone

q = Question(subject='pybo가 무엇인가요?', content='pybo에 대해서 알고 싶습니다.', create_date=timezone.now())

q.save()

 

save로 question을 생성하고 저장하였다. 질문 한 개 더 만들어보자

 

q = Question(subject='장고 모델 질문입니다.', content='id는 자동으로 생성되나요?', create_date=timezone.now())

q.save()

q.id

 

save하고 q.id로 질문이 몇 개 있는 확인하였다. id는 모델 데이터의 PK이다. 질문 2개를 만들었으니, 2개라고 뜨는 것을 확인할 수 있다.

 

Question 조회

 

Question.objects.all()

Question의 데이터를 조회하는 함수이다. Question object (1)이라고 뜨는데 id가 1인 Question object라는 뜻이다

 

Question 모델에 __str__ 메서드를 추가하면 괄호 안에 id 값이 아니라 제목이 표시되도록 할 수 있다.

 

파일 : C:\projects\mysite\pybo\models.py

 

Question 클래스 하위에 __str__을 추가해주면, 이제 제목이 표시된다.

다시 Question.objects.all() 함수를 실행해보자. 참고로 장고 셸을 재시작해야 코드 변경이 반영된다.

 

이제 제목이 표시되는 것을 확인할 수 있다.

 

모델에 메서드가 추가될 경우는 makemigrations와 migrate를 수행할 필요가 없다.

migrate 명령을 해야 하는 경우는 모델의 속성이 변경되었을 때 뿐이다.

 

filter와 get으로 id 값이 1인 Question 데이터 조회

 

Question.objects.filter(id=1)

Question.objects.get(id=1)

 

filter는 조건에 해당하는 데이터를 모두 조회하고, get은 조건에 맞는 데이터 한 건을 조회한다.

그리하여 여러 건을 리턴하는 QuerySet을 리턴하고, get은 Question 모델 객체를 리턴한다.

 

filter로 "장고"라는 문자열이 포함된 데이터만 조회할 수도 있다.

 

Question.objects.filter(subject__contains='장고')

 

Question 수정

 

q = Question.objects.get(id=2)

q.subject = 'Django Model Question'

q.save()

 

id 값이 2인 Question의 제목을 '장고 모델 질문입니다.' 에서 'Django Model Quesiton'으로 바꾸었다.

바꿀 때마다 q로 확인해보면, 잘 변경되었음을 알 수 있고 마지막에 save로 저장해주었다.

 

Question 삭제

 

q = Question.objects.get(id=1)

q.delete()

Question.objects.all()

 

Question 객체가 선언된 q를 delete로 삭제한다. 마지막에 Question.objects.all()로 조회하면 2개였던 Question 객체가 1개만 조회됨을 확인할 수 있다.

 

Answer 작성

 

q = Questin.objects.get(id=2)

q

from django.utils import timezone

a = Answer(question=1, content='네 자동으로 생성됩니다.', create_date=timezone.now())

a.save()

a.id

 

답변 데이터를 만들려면 질문 데이터가 필요하다. id가 2인 질문을 먼저 조회한 후 question 속성에 대입한다.

이후에 Answer 모델도 id가 자동으로 생성되므로, id를 조회하면 Answer가 잘 생성된 것을 알 수 있다.

 

Answer 조회

 

a = Answer.objects.get(id=1)

a

a.question

q.answer_set.all()

 

Answer 객체가 선언된 a를 사용하여 a.question으로 답변에 연결된 질문을 조회할 수 있다.

그리고 answer_set.all()로 질문을 통하여 답변을 찾는 것 또한 가능하다.

 

 


※ 본 내용은 django 공부 기록이며, 점프 투 장고를 참고하였습니다.

https://wikidocs.net/book/4223

 

점프 투 장고

**점프 투 장고 오프라인 책 출간 !! (2020.12)** * [책 구입 안내](https://wikidocs.net/105844)

wikidocs.net