[1] Django ORM 개요
ORM이란 Object-Relational Mapping의 약자로 객체(Object)와 관계형 데이터베이스(Relational Database)의 데이터를 매핑(Mapping)해주는 것을 의미한다. 객체 간의 관계를 바탕으로 SQL을 자동 생성하여 sql쿼리문 없이도 데이터베이스의 데이터를 다룰 수 있게 해준다.
데이터베이스의 테이블을 객체지향 프로그래밍에서 흔히 사용하는 객체(Class)처럼 사용할 수 있도록 해주는 기술이다.
기존 쿼리문을 작성하여 데이터베이스를 조작하는 것을 넘어서서 더 효율적이고 가독성 및 유지 보수에 적합한 코드를 만들기 위해 나온 기술이다.
예시
book 이라는 객체에서 저자의 이름이 kim 인 책 목록을 가져오고 싶을 때,
SQL 쿼리문을 사용할 경우
book_list = new list();
sql = "SELECT book FROM library WHERE author = 'kim'";
data = query(sql);
while (row = data.next()){
book = new Book();
book.setAuthor(row.get('author')); book_list.add(book);
}
|
sql 쿼리문을 작성하고, 데이터를 가져오는 일련의 모든 과정들을 코드에 적어야 한다.
ORM을 사용할 경우
book_list = BookTable.query(author="kim")
|
간단하게 한 줄로 원하는 객체를 가져올 수 있다.
ORM 활용
데이터 가져오기
objects.all()
>>> Book.objects.all() <QuerySet [<Book: one>, <Book: two>]>
|
Book객체에 저장된 데이터를 모두 가져올 수 있다.
objects.get()
>>> Book.objects.get(author='kim')
|
데이터 추가하기
objects.create()
>>> Book.objects.create(title='Developer', author='hyelyn')
|
데이터 모델 Book객체에 정의된 title과 author 필드에 데이터를 넣어 새로운 데이터를 추가할 수 있다.
()
>>> book = Book() >>> book.title = 'Hyelyn Potter' >>> book.author = 'hyelyn' >>> book.save()
|
데이터 검색
objects.filter()
>>> Book.objects.filter(author='heylyn') <Queryset [<Book: one>, <Book: two>]>
|
filter의 반환 값을 쿼리셋(Queryset)이라는 Django ORM에서 발생한 자료형이다.
쿼리셋은 데이터베이스에서 전달받은 객체들의 목록을 담고있다.
리스트 구조와 같아서 리스트 사용하는 것과 같이 사용할 수 있디.
데이터 삭제
objects.delete()
>>> d = Book.objects.get(title='Developer') >>> d.delete() # 삭제 완료.
|
Django ORM이 실행하는 실제 SQL 질의문 확인하는 방법
django ORM을 활용하여 데이터를 다루는 것이 편할 수는 있지만, 데이터에 대해 이해하고 더 잘 다루기 위해서는 SQL 질의문이 어떤 식으로 데이터를 다루는지 확인하고 ORM을 사용하면 더 효과적으로 사용할 수 있다.
django에서 SQL 질의문을 구하는 것은 간단하다.
Book이라는 모델이 있고 이 모델의 모든 행을 읽어올 때 Book.objects.all() 과 같은 코드를 작성하면 된다. 이렇게 구한 쿼리셋을 내장 함수인 query를 str형태로 출력하면 SQL 질의문을 확인할 수 있다.
>>> queryset = Book.objects.all()
>>> str(queryset.query)
SELECT "appname_book"."id", "appname_book"."title","appname_book"."author" FROM "appname_book"
|
Django ORM으로 연산하는 방법
OR
OR연산으로 여러 조건 중 하나라도 만족하는 행을 구해야 하는 경우가 있다. 예를 들어 Book 데이터베이스 중 title이 A이거나 B인 데이터를 구해야 한다면 다음과 같은 방법을 사용할 수 있다.
queryset_1 | queryset_2
>>> queryset = Book.objects.filter(title="A")| Book.objects.filter(title="B")
|
filter(Q(<condition_1>|Q(<condition_2>)
Q 사용 시 모듈을 import 해야 한다.
>>> from django.db.models import Q
>>> Book.objects.filter(Q(title="A") | Q(title="B"))
|
AND
AND 연산으로 여러 조건을 모두 만족하는 행을 구해야 하는 경우는 다음과 같은 방법으로 사용할 수 있다.
filter(<condition_1>, <condition_2>)
>>> queryset = Book.objects.filter(title="A", title="B")
|
queryset_1 & queryset_2
>>> queryset = Book.objects.filter(title="A") & Book.objects.filter(title="B")
|
filter(Q(<conditione_1>) & Q(<condition_2>))
>>> from django.db.models import Q
>>> queryset = Book.objects.filter(Q(title="A") & Q(title="B"))
|
NOT
Book 모델의 데이터베이스 중 title이 'A'가 아닌 데이터가 필요한 경우 다음과 같이 구할 수 있다.
exclude(<condition>)
>>> queryset = Book.objects.exclude(title="A")
|
filter(~Q(<condition>))
>>> from django.db.models import Q
>>> queryset = Book.objects.filter(~Q(title="A"))
|
ORM의 장점
SQL query가 아닌 직관적인 코드로 (메소드) 데이터를 조작할 수 있어 개발자가 객체모델로 프로그래밍하는 데 집중할 수 있다.
각 객체에 대한 코드를 별도로 작성하기 때문에 코드 가독성이 좋다.
SQL의 절차적이고 순차적인 접근이 아닌 객체 지향적인 접근으로 생산성이 좋다.
ORM의 단점
프로젝트 복잡성이 커질 경우 난이도가 높아진다.
잘못 구현하게 되면 속도가 저하되고 일관성이 없어질 수 있다.
sql 쿼리문으로 다루지 않다 보니 정확한 원리를 이해하는데 어려움이 발생할 수 있다.
[2] django ORM 세팅
1. Model 생성
1) models.py에 클래스 추가 (class명이 table 이름)
from django.db import models
class Guest(models.Model):
title = models.CharField(max_length=50);
content = models.TextField();
regdate = models.DateField(auto_now_add=True);
def __str__(self):
return self.title;
2) admin.py에 등록 - 관리자 페이지에서 조회 할수 있도록 등록
from django.contrib import admin
from hello.models import Guest
class GuestAdmin(admin.ModelAdmin):
list_display = ('id','title','content','regdate');
admin.site.register(Guest,GuestAdmin);
2. django database setting
- MariaDB 에서 'NAME'에 들어가 있는 database에 접속하도록 설정
- 파일 : config/settings.py
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'shop',
'USER': 'root',
'PASSWORD': '111111',
'HOST': '127.0.0.1',
'POST': '3306'
}
}
3. Migration (python terminal에서)
--> python manage.py makemigrations
--> python manage.py migrate
4. django 관리자 생성 (python terminal에서)
--> python manage.py createsuperuser
5. 서버 연결 후 관리자 페이지로 접속
--> python manage.py runserver 80
- 관리자 페이지 --> 127.0.0.1/admin
6. HeidiSQL 접속 및 테이블 확인
7. HeidiSQL에서 테이블이 추가될 경우
- 관리자 페이지에 바로 반영되지 않음
- 관리자 페이지에 추가된 테이블 반영하려면 다음 과정을 진행
1) 기존 테이블 정보 조회(python terminal에서)
--> python manage.py inspectdb
- HeidiSQL에 뜨는 모든 테이블 확인 가능 (model.py에 들어가는 형식의 class로 테이블 확인 가능)
2) 위 테이블 정보를 python파일로 받기 (파일명을 a로 할 경우)
--> python manage.py inspectdb > a.py
3) a.py에서 추가된 테이블(class) 찾아서 model.py 내에 복붙

4) admin.py 에 테이블 등록
- model.py 의 class에서는 autoincrement 형식의 id는 입력이 안되어 있음.
- HeidiSQL에서 테이블에 id가 있다면, 잊지말고 list_display에도 넣어줘야 함.
- ex> 위 사진의 model.py 에서 Item과 Cart에는 id가 안나오지만, 실제 테이블에는 id가 있으므로,
아래 사진의 admin.py에 list_display 안에는 넣어줘야 함)
