[django] ORM & CRUD
📌django
django 동작 흐름
- 요청과 응답 - web client가 정보를 요청하면 데이터 베이스는 필요한 정보를 응답한다
이 과정에서 장고의 역할은 URLconf 클라이언트 요청을 분리하고, View 에소 요청을 처리하기 위한 로직를 처리하고, Model 에서 데이터 처리를 한다.
이 과정을 둘로 나눠서 본다면 통신 및 요청 처리와 데이터 처리(Model과 ORM)로 볼수 있다.
📌 ORM
- Object Relational Mapping : 객체-관계 매핑
- 객체(클래스)와 관계형 데이터베이스(테이블)의 데이터를 자동으로 매핑(연결)해주는 것을 말한다.
- 클래스와 테이블은 서로가 기존부터 호환가능성을 두고 만들어어진 것이 아니기 때문에 불일치가 발생하는데 이를 ORM을 통해 객체 간의 관계를 바탕으로 SQL문을 자동으로 생성해 불일치를 해결한다.
- 객체 하나당 테이블 하나, 속성 하나당 칼럼을 말한다.
- QuerySet이란?
쿼리셋은 데이터베이스에 있는 객체의 모음을 말한다. 각 객체들은 데이터베이스에서 하나의 record(row)에 해당한다. python에서 작성한 코드가 sql로 매핑되어 QuerySet이라는 자료형태로 값이 넘어온다. 이 쿼리셋으로 데이터베이스로부터 데이터를 읽고, 필터를 걸거나 정렬할 수 있다. 쿼리셋은 데이터베이스와 소통하기 위한 자료형이다.
- make migrations
- 데이터베이스에 적용하기 위한 설계도를 만드는 것. 즉 파이썬 코드를 sql로 바꾸기 위한 일종의 설계도를 말한다.
- migrate
- 위의 설계도를 실행하는 것을 말한다.
📌 CRUD
📍 헷갈리지 말것
- model class는 databases의 테이블, model class의 instance(객체)는 database table의 각각의 record를 말한다.
- create
- 클래스에 3가지 속성(칼럼)이 있으면 다 채워야지 생성된다. 만약 비어있다면 디폴트 값이나 널 값을 꼭 정의해줘야한다.
- QuerySet이란?
쿼리셋은 데이터베이스에 있는 객체의 모음을 말한다. 각 객체들은 데이터베이스에서 하나의 record(row)에 해당한다. python에서 작성한 코드가 sql로 매핑되어 QuerySet이라는 자료형태로 값이 넘어온다. 이 쿼리셋으로 데이터베이스로부터 데이터를 읽고, 필터를 걸거나 정렬할 수 있다. 쿼리셋은 데이터베이스와 소통하기 위한 자료형이다.
📍 헷갈리지 말것
- model class는 databases의 테이블, model class의 instance(객체)는 database table의 각각의 record를 말한다.
- create
- 클래스에 3가지 속성(칼럼)이 있으면 다 채워야지 생성된다. 만약 비어있다면 디폴트 값이나 널 값을 꼭 정의해줘야한다.
1. create()
함수로 만들기
>>> c1 = Category.objects.create(name="쿠키",menu_id=2)
>>> c1
<Category: Category object (7)> #인스턴스 반환
c1
2. 모델 instance의 save함수를 통해 만들기
>>> c2 = Category(name="쿠키",menu_id=2)
>>> c2.save() #꼭 저장을 해야함.
>>> c2
<Category: Category object (8)>
- read
get()
- 쿼리셋이 아닌, 인스턴스를 하나만 반환해준다. 따라서
get()
를 사용할 경우 unique한 한 값을 검색하는 것이 좋다 - 만약 객체가 없으면
DoesNotExist
에러가 발생하고, 여러개의 객체가 조회되면MultipleObjectsReturned
에러가 발생한다.
>>> m = Menu.objects.get(id=1)
>>> m
<Menu: Menu object (1)> #인스턴스
>>> m.name
'음료'
filter()
- 조건에 맞는 여러개의 인스턴스를 포함하는 쿼리셋을 반환한다. filter()의 경우, 키워드 검색이라서 특정 조건을 만족하는 인스턴스를 검색할 때 이용할 수 있다. 중복도 가능하다. 그리고 결과를 쿼리셋으로 반환한다.
>>> m3 = Menu.objects.filter(id=2)
>>> m3
<QuerySet [<Menu: Menu object (2)>]> #쿼리셋
>>> p = Product.objects.filter(category_id=1) #category_id가 2인 객체 다 가져오기
>>> p
<QuerySet [<Product: Product object (1)>, <Product: Product object (2)>]>
>>> pp = Product.objects.filter(name="바닐라 콜드 브루")
>>> pp
<QuerySet [<Product: Product object (1)>]>
- get과 filter의 차이
get은 인스턴스 하나를 가져오고, 필터는 쿼리셋를 가져온다. 따라서 어떤 데이터를 가져오냐에 따라서 사용을 달리하면 된다. 쿼리셋은 쿼리셋를 반환하기 때문에 인덱싱 할 수 있다.- 값이 없을 때 get()은
DoesNotExist
을 가져오고, 쿼리셋은 빈 쿼리셋을 가져온다. 그리고 get()은 쿼리셋을 호출하는 것이 아니기 때문에 뒤에 다른 메소드를 추가할 수 없다.
all()
- 쿼리셋 전체를 다 가져온다. 쿼리셋을 return한다.
>>> Product.objects.all()
<QuerySet [<Product: Product object (1)>, <Product: Product object (2)>, <Product: Product object (3)>, <Product: Product object (4)>]>
# 전체를 가져와서 활용가능
>>> a = Menu.objects.all()
>>> type(a)
<class 'django.db.models.query.QuerySet'>
>>> a[0]
<Menu: Menu object (1)>
>>> a[1]
<Menu: Menu object (2)>
>>> for i in a: #for문 사용도 가능
... print(i)
...
Menu object (1)
Menu object (2)
Menu object (3)
Menu object (4)
Menu object (5)
Menu object (6)
- update
- db 데이터 수정하기
# 모델 인스턴스(객체) 속성을 변경하기
>>> update_instance = Category.objects.get(id=7) #category_id가 7인 객체를 인스턴스에 저장
>>> update_instance
<Category: Category object (7)>
>>> update_instance.name = "샌드위치" #이름을 수정하기
>>> update_instance.save() #save를 하기 전에 파이썬 코드에서만 적용된것이므로 저장 필요
>>> update_instance
<Category: Category object (7)>
- delete
- 쿼리셋,인스턴스 둘다 가능하다.
#인스턴스 삭제
>>> post_instance = Category.objects.get(id=8)
>>> post_instance.delete()
(1, {'products.Category': 1})
#쿼리문 삭제
>>> mm = Menu.objects.filter(id=5)
>>> mm.delete()
(1, {'products.Menu': 1})
Model methods
Author And Source
이 문제에 관하여([django] ORM & CRUD), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@byhazy/django-ORM-CRUD저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)