Web/Django

Django ORM을 활용한 모델(model) 생성 및 데이터 처리하기

daeunnniii 2021. 8. 1. 02:38
728x90
반응형

모델(Model)

1. Django App migrate 하기

Django는 모델(Model)이라는 것을 이용해서 데이터베이스를 처리한다.

보통의 데이터베이스는 SQL 쿼리문을 통해 데이터를 추가, 수정, 삭제, 조회를 하지만 장고의 모델(Model)을 이용하면 이러한 쿼리문 없이 데이터를 쉽게 처리할 수 있다.

settings.py를 보면 INSTALLED_APPS에서 설치된 앱들을 볼 수 있다. 아래 앱들은 장고 프로젝트 생성 시 기본적으로 설치되는 앱들이다. 

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

또한 settings.py의 DATABASES 부분에 데이터베이스에 대한 정보도 확인할 수 있다.

데이터베이스 파일은 BASE_DIR 디렉터리 밑에 db.sqlite3 파일에 저장된다고 한다.

여기서 BASE_DIR은 프로젝트가 들어있는 폴더 경로\프로젝트이다.

추가적으로 SQLite는 소규모 프로젝트에서 사용되는 가벼운 파일 기반의 데이터베이스이다.

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

 이제 터미널에 python manage.py migrate 명령어를 입력하여 admin, auth, contenttypes, sessions 앱들이 필요로하는 테이블을 생성할 것이다. 이 테이블을 우리가 직접 건드릴 일은 없다.

2. 모델 작성하기

일단 간단하게 질문과 답변을 할 수 있는 파이썬 게시판을 만들어볼 것이다.

질문 모델에는 질문의 제목, 내용과 질문을 작성한 일시에 대한 속성을 가져야하고, 답변 모델에는 해당 질문, 답변의 내용, 답변 작성 일시에 대한 속성을 가져야한다.

이제 App 폴더인 notes의 models.py에서 다음과 같이 작성한다.

from django.db import models

# Create your models here.
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자까지 가능하도록 설정했다. (max_length=200)

이렇게 글자수의 길이가 제한된 텍스트는 CharField를 사용해야 한다!

그리고 글자수를 제한할 수 없는 텍스트는 위처럼 TextField를 사용한다.

 

이제 Answer 모델을 살펴보면,

question의 경우 Question 모델을 속성으로 가진다는 의미이다. 이는 기존 모델을 외래키 속성으로 연결하기 위해 ForeignKey를 활용한다. 여기서 on_delete=models.CASCADE는 해당 Question이 삭제될 경우 그에 해당하는 Answer도 삭제된다는 의미이다.

 

이외의 속성 타입은 아래 링크에서 참고:

https://docs.djangoproject.com/en/3.0/ref/models/fields/#field-types

 

 

3. notes 앱에 등록하기

테이블 생성을 위해선, 먼저 settings.py에서 INSTALLED_APPS 항목에 추가해야한다!

notes.apps.PyboConfig 클래스는 notes/apps.py 파일에 있는 클래스이다.

INSTALLED_APPS = [
    'notes.apps.NotesConfig',		#추가
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 

4. makemigrations

모델이 신규로 생성되거나 변경되면 makemigrations 명령어를 수행해주어야한다.

따라서 python manage.py makemigrations 를 터미널 창에 입력한다. 그러면 migrations 폴더에 0001_initial.py 파일이 자동으로 생성된다. 

들어가서 확인해보면 다음과 같이 id라는 필드가 자동으로 추가되어 primary key로 설정된다.

아직 실제로 테이블이 생성되지는 않았다. 

makemigrations 명령은 Django가 테이블 작업을 수행하기 위한 작업 파일(예: 0001_initial.py)을 생성하는 명령어다. 실제 테이블 생성은 migrate 명령을 통해서만 가능하다.

 

여기서 추가적으로, sqlmigrate 명령을 활용하면 실행되는 쿼리를 조회할 수 있다.

ex) python manage.py sqlmigrate notes 0001

 

5. migrate

이제 migrate 명령을 수행하면 실제 테이블을 생성할 수 있다.

python manage.py migrate

 

모델(Model) 사용법

아래와 같이 입력하면 장고 셸을 실행할 수 있다.

python manage.py shell

위에서 생성한 Question과 Answer 모델은 장고 셸에서 아래와 같이 import하여 사용할 수 있다.

from pybo.models import Question, Answer

 

1) 데이터 생성

create_date 속성은 DateTimeField 타입이므로 timezone.now()로 현재일시를 대입한다.

save 함수를 실행하면 데이터 1건이 생성된다. 위에서 자동으로 숫자가 증가하는 id라는 필드가 숨어있는 것을 확인했으므로 아래 데이터는 id=1 속성 값을 갖게 된다.

> from django.utils import timezone
> q = Question(subject='notes가 무엇인가요?', content='notes에 대해서 알고 싶습니다.', create_date=timezone.now())
> q.save()

 

한번 더 생성해보자.

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

여기서 id=2라는 속성 값을 갖게 될 것이다. q 객체의 id 속성을 확인해보면 2가 출력되는 것을 확인할 수 있다.

> q.id
2

 

2) 데이터 조회

Question.objects을 통해 데이터를 조회할 수 있고, Question.objects.all()을 통해 모든 데이터를 조회할 수 있다. 기본적으로 id 값을 조회할 수 있다.

> Question.objects.all()
<QuerySet [<Question: Question object (1)>, <Question: Question object (2)>]>

하지만 우리가 궁금한 것은 질문의 제목이므로 id 값 대신 제목을 표시하도록 설정할 것이다.

models.py에서 다음과 같이 __str__메서드를 추가해준다.

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

    def __str__(self):
        return self.subject

모델이 변경된 것이 아닌 모델에 메서드가 추가된 경우에는 makemigrations와 migrate를 수행할 필요 없다. 단 장소 셸은 다시 열어줘야한다.

filter() 함수로 해당 조건에 대한 데이터를 확인할 수 있다. 조건에 해당하는 데이터가 여러 개일 경우 모두 출력한다.

> Question.objects.filter(id=1)
<QuerySet [<Question: notes가 무엇인가요?>]>

filter()의 옵션으로 subject__contains를 활용하면 특정 문자열이 포함되어있는 데이터를 조회할 수 있다.

 

추가적으로 filter()와 달리, get() 함수는 한건만 리턴하므로, 조건에 기본키와 관련된 조건을 넣어주어야할 것이다.

 

3) 데이터 수정

아래와 같이 특정 데이터를 조회하여 q라는 객체에 넣는다. 

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

그리고 subject 속성을 다음과 같이 수정한 뒤 꼭 save() 를 적용해준다. save()를 적용해주어야 데이터 수정이 반영된다!

> q.subject = 'Django Model Question'
> q.save()

 

4) 데이터 삭제

마찬가지로, 특정 데이터를 조회하여 q라는 객체에 넣었다.

그리고 delete()를 수행하면 해당 데이터가 삭제된다. 아래와 같이 추가정보가 리턴되는데, 여기서 첫번째 숫자는 삭제된 데이터의 갯수, 뒤의 숫자는 모델별 삭제된 숫자를 의미한다.

> q = Question.objects.get(id=1)
> q.delete()
(1, {'pybo.Question': 1})

 

5) 외래키로 연결된 데이터 작성

위에서 Question 모델을 Answer의 속성으로 포함했다. 이렇게 외래키로 연결된 데이터를 어떻게 작성하는지 알아보자.

먼저 외래키로 연결할 해당 Question 모델의 데이터를 q 변수에 넣어준다.

그리고 외래키로 연결될 Answer의 데이터를 q를 활용하여 추가해준다. save()를 꼭 적용해주어야한다는 점 주의하자!!

> q = Question.objects.get(id=2)
> from django.utils import timezone
> a = Answer(question=q, content='네 자동으로 생성됩니다.', create_date=timezone.now())
> a.save()

 

6) 외래키로 연결된 데이터를 통해 외래키로 연결한 데이터 조회하기

연결모델명_set (예:answer_set)을 활용하면 질문에 연결된 답변을 가져올 수 있다. 단, 질문 하나에는 여러개의 답변이 가능하므로 q.answer_set이 가능하지만 답변 하나에는 여러개의 질문이 있을 수 없으므로 a.question_set은 불가능하다. 이것은 하나의 기본키를 여러 외래키가 참조할 수 있지만, 하나의 외래키가 여러 개의 기본키를 참조할 수 없다는 것과 같다.

> q.answer_set.all()
<QuerySet [<Answer: Answer object (1)>]>

 

 

 

 

 

 

 

참고: https://wikidocs.net/70650

 

 

 

 

 

 

728x90
반응형