[django] ORM & CRUD

ㅎㅎ·2021년 6월 20일
0

django

목록 보기
5/8

📌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가지 속성(칼럼)이 있으면 다 채워야지 생성된다. 만약 비어있다면 디폴트 값이나 널 값을 꼭 정의해줘야한다.

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

더 자세한 설명

0개의 댓글