Django는 웹 애플리케이션의 데이터를 구조화하고 조작하기 위한 추상적인 계층(Model)을 제공한다.
Model의 핵심 개념과 ORM을 통해 데이터베이스를 조작하는 방법에 대해 알아보자.
$ django-admin startproject crud .
$ python manage.py startapp articles
# settings.py
INSTALLED_APPS = [
'articles',
...
]
models.py
작성# articles/models.py
class Article(models.Model):
title = models.CharField(max_length=10)
content = models.TextField()
CharField(max_length=None, **options)
TextField(**options)
지금까지 작성한 models.py는 데이터베이스 스키마를 정의한 것이다.
이제 이러한 모델의 변경사항을 실제 데이터베이스에 반영하기 위한 과정이 필요하다.
migrations/0001_initial.py
가 생성된 것을 확인$ python manage.py makemigrations
$ python manage.py migrate
showmigrations
$ python manage.py showmigrations
sqlmigrate
$ python manage.py sqlmigrate articles 0001
makemigrations
migrate
이제 ORM을 통해 DB를 객체로 조작하는 방법에 대해 알아보자.
[Model class].[Manager].[Queryset API]
article = Article()
# 특정 테이블에 새로운 행을 추가하여 데이터 추가
>>> article = Article() # Article(class)로부터 article(instance)
>>> article
<Article: Article object (None)>
>>> article.title = 'first' # 인스턴스 변수(title)에 값을 할당
>>> article.content = 'django!' # 인스턴스 변수(content)에 값을 할당
# save 를 하지 않으면 아직 DB에 값 저장되지 않음
>>> article
<Article: Article object (None)>
>>> Article.objects.all()
<QuerySet []>
# save를 하고 확인하면 저장된 것 확인할 수 있다.
>>> article.save()
>>> article
<Article: Article object (1)>
>>> article.id
1
# DB 테이블의 컬럼 이름이 id임에도 pk를 사용할 수 있는 이유는 Django가 제공하는 shortcut이기 때문
>>> article.pk
1
>>> Article.objects.all()
<QuerySet [<Article: Article object (1)>]>
# 인스턴스인 article을 활용하여 변수에 접근하기
>>> article.title
'first'
>>> article.content
'django!'
article.title
# 인스턴스 생성시 초기값을 함께 작성하여 생성
>>> article = Article(title='second', content='django!')
# 아직 저장되어 있지 않음
>>> article
<Article: Article object (None)>
# save 호출해야 저장
>>> article.save()
>>> article
<Article: Article object (2)>
>>> Article.objects.all()
<QuerySet [<Article: Article object (1)>, <Article: Article object (2)>]>
# 값 확인
>>> article.pk
2
>>> article.title
'second'
>>> article.content
'django!'
article.save()
# 위 2가지 방식과는 다르게 바로 생성된 데이터가 반환된다.
>>> Article.objects.create(title='third', content='django!')
<Article: Article object (3)>
.save()
all()
>>> Article.objects.all()
<QuerySet [<Article: Article object (1)>, <Article: Article object (2)>, <Article: Article object (3)>]>
get()
>>> Article.objects.get(pk=1)
<Article: Article object (1)>
>>> Article.objects.get(pk=100)
DoesNotExist: Article matching query does not exist.
>>> Article.objects.get(content='django!')
MultipleObjectsReturned: get() returned more than one Article -- it returned 3!
Filter
>>> Article.objects.filter(content='django!')
<QuerySet [<Article: Article object (1)>, <Article: Article object (2)>, <Article: Article object (3)>]>
>>> Article.objects.filter(title='ssafy')
<QuerySet []>
In [35]: Article.objects.filter(title='first')
<QuerySet [<Article: Article object (1)>]>
Field lookups
filter()
, exclude()
및 get()
에 대한 키워드 인자로 지정됨# Field lookups 예시
# content 칼럼에 'dj'가 포함된 모든 데이터 조회
>>> Article.objects.filter(content__contains='dj')
<QuerySet [<Article: Article object (1)>, <Article: Article object (2)>, <Article: Article object (3)>]>
>>> article = Article.objects.get(pk=1)
# 인스턴스 변수 변경
>>> article.title = 'byebye'
# 저장
>>> article.save()
# 정상적으로 변경 된 것 확인
>>> article.title
>>> 'byebye'
>>> article = Article.objects.get(pk=1)
# delete 메서드 호출
>>> article.delete()
(1, {'articles.Article': 1})
# 1번 데이터는 이제 조회할 수 없음
>>> Article.objects.get(pk=1)
DoesNotExist: Article matching query does not exist.