<Django>Queryset API

jm_yoon·2020년 12월 27일
1

Queryset?

데이터베이스에서 전달 받은 모델의 객체 목록이다.(Django ORM에서 발생한 자료형)
데이터베이스의 여러 row를 담은 형태이다.
리스트와 구조는 같지만 파이썬 기본 자료구조가 아니기 때문에 파이썬에서 읽고 쓰기 위해 자료형 변환(Casting)을 해줘야한다.

Queryset CRUD

Create 데이터 생성/입력
Read 데이터 조회
Update 데이터 수정
Delete 데이터 삭제

Create 데이터 생성/입력

  • SQL의 INSERT와 같이 동작한다.
  • creat() 와 save()가 있다.

create()

Table에 데이터를 추가(INSERT) 해주는 method로, 생성된 인스턴스를 반환해준다.

In [4]: category=Category.objects.create(name="커피",menu_id=1)

In [5]: category.name #인스턴스로 반환되므로 category.name으로 class안에 변수에 접근할 수 있다.
Out[5]: '커피'

In [6]: Menu.objects.create(name="샐러드")
Out[6]: <Menu: Menu object (11)>

bulk_create()

객체 리스트를 DB에 삽입한다.(한번에 여러 객체를 저장)
단, 주의사항이 있음

  • save()가 호출되지 않기 때문에 pre_save, post_save 시그널이 발생하지 않는다.
  • 다중 테이블 상속 시나리오에서는 하위 모델과 작동하지 않는다.
  • 모델의 기본 키가 AuthField인 경우 DB 백엔드가 지원하지 않는 다면(PostgreSQL) 기본 키 속성을 검색하여 설정하지 않는다.
  • many-to-many 관계는 지원하지 않는다.
In [134]: Menu.objects.bulk_create([Menu(name="샌드위치",id=5),Me
     ...: nu(name="케이크",id=6)])
Out[134]: [<Menu: Menu object (5)>, <Menu: Menu object (6)>]

save()

save method는 INSERT또는 UPDATE

In [7]: Drink(name="루이보스티").save()

Read 데이터 조회

  • DB의 내용을 조회하기 위해 QuerySet객체를 사용한다.(DB의 객체를 꺼내 담은 컬랙션이 Queryset)
  • Queryset은 SQL의 SELECT와 같이 동작한다.

all()

모든 row들을 가져오는 메소드이며 QuerySet 을 반환한다.
이때 QuerySet안에는 각각 인스턴스가 포함되어 있다.

In [11]: Menu.objects.all()
Out[11]: <QuerySet [<Menu: Menu object (1)>, <Menu: Menu object (2)>, <Menu: Menu object (3)>, <Menu: Menu object (4)>, <Menu: Menu object (5)>, <Menu: Menu object (6)>, <Menu: Menu object (7)>, <Menu: Menu object (8)>, <Menu: Menu object (9)>, <Menu: Menu object (10)>, <Menu: Menu object (11)>]>

In [12]: for menu in Menu.objects.all():
    ...:     print(menu.name)
    ...:
음료
푸드
상품
카드
샌드위치
케이크
베이커리
상품권
텀블러
머그컵
샐러드

filter()

특정 칼럼값을 지정하여 조건에 해당하는 레코드를 QuerySet에 담는다.

In [13]: Menu.objects.filter(name="음료")
Out[13]: <QuerySet [<Menu: Menu object (1)>]>

exclude()

조건에 맞는 값을 제외하여 레코드를 QuerySet에 담는다.

In [14]: Menu.objects.exclude(name="음료")
Out[14]: <QuerySet [<Menu: Menu object (2)>, <Menu: Menu object (3)>, <Menu: Menu object (4)>, <Menu: Menu object (5)>, <Menu: Menu object (6)>, <Menu: Menu object (7)>, <Menu: Menu object (8)>, <Menu: Menu object (9)>, <Menu: Menu object (10)>, <Menu: Menu object (11)>]>

exists()

filter()와 함께 사용해서 filter 조건에 맞는 데이터가 있는지 조회하는 메소드이다.
존재하면 True 존재하지 않으면 False를 반환한다.

In [25]: Drink.objects.filter(name="녹차").exists()
Out[25]: True

valuse()

Queryset 결과의 내용을 dictionary(딕셔너리)형태의 element를 담은 리스트형태로 반환한다.

In [17]: Menu.objects.filter(name="음료").values()
Out[17]: <QuerySet [{'id': 1, 'name': '음료'}]>

valuse_list()

Queryset 결과의 내용을 tuple(튜플)형태의 element를 담은 리스트형태로 반환한다.
key는 없고, 오로지 value만 튜플형태로 담음

values_list() method는 dictionary를 반환하는 대신 반복 될 때 튜플을 반환한다는 점을 제외하면 values ()와 유사하다. 각 튜플에는 values_list () 호출에 전달 된 각 필드 또는 표현식의 값이 포함되어 있으므로 첫 번째 항목이 첫 번째 필드이다.

In [18]: Menu.objects.filter(name="음료").values_list()
Out[18]: <QuerySet [(1, '음료')]>

get()

  • 하나의 row만 가져오기 위한 메소드
  • Queryset이 아닌 모델 객체를 반환하는 메소드(특정 column 조건에 해당하는 결과를 객체로 반환하는 함수)
  • get()은 쿼리셋을 호출하는 것이 아니라서 뒤에 다른 메소드를 추가할 수 없음
  • 값은 1개만 불러옴

    filter()와 다른 점
    값이 없을 때 filter()는 빈 쿼리셋을 불러 오지만 get()은 DoesNotExist라는 메시지를 띄운다.
    해당하는 값이 한 개가 아닐 경우에는 MultipleObjectsReturned라는 메시지를 띄운다.
    그러므로 try-except 구문 등으로 예외처리를 해주는 것이 좋다.

In [19]: Drink.objects.get(id=41)
Out[19]: <Drink: Drink object (41)>

In [23]: drink=Drink.objects.get(id=41)
In [24]: drink.name
Out[24]: '레몬티'

get_or_creat()

  • 단일객체(object, created)를 반환하고, 없으면 생성한다.
  • 튜플 형태로 반환
  • 데이터를 가져올때(get)는 False, 데이터가 생성될 때는 True
In [123]: drink=Drink.objects.get_or_create(name="레몬티",categor
     ...: y_id=7)

In [124]: drink[0]
Out[124]: <Drink: Drink object (41)>

In [125]: drink[1]
Out[125]: True

In [126]: drink[0].name
Out[126]: '레몬티'

In [156]: drink=Drink.objects.get_or_create(name="녹차")

In [157]: drink[0]
Out[157]: <Drink: Drink object (37)>

In [158]: drink[1]
Out[158]: False

In [159]: drink[0].name
Out[159]: '녹차'

In [149]: Drink.objects.get_or_create(name="자몽티")
Out[149]: (<Drink: Drink object (42)>, True)

count()

QuerySet과 일치하는 DB 객체의 수를 나타내는 정수를 반환한다.
데이터의 갯수(row의 수)를 세주는 메소드

  • count()는 SELECT COUNT(*)를 수행하므로, 모든 레코드를 파이썬 객체에 로드하고 len()를 호출하는 것보다는 count()를 사용해야한다.(객체를 메모리에 로드하지 않을때는 len()이 더 빠르다.)
In [160]: Menu.objects.count()
Out[160]: 10

first()

데이터들 중 처음에 있는 row를 반환한다.
QuerySet과 일치하는 첫 객체를 반환하는데, 정렬을 정의하지 않으면 pk로 자동 정렬한다. order_by() 와 상호작용에 영향을 미칠 수 있다.

In [163]: menu=Menu.objects.all()

In [164]: menu.first()
Out[164]: <Menu: Menu object (1)>

In [165]: menu[0].name
Out[165]: '음료'

last()

QuerySet과 일치하는 마지막 객체를 리턴한다. 그외에는 first()와 동일하다.

In [168]: menu=menu.last()

In [169]: menu.name
Out[169]: '머그컵'

aggregate()

aggregate의 사전적 의미는 '합계', '종합'이다. Django에서는 필드 전체의 합이나 평균, 개수 등을 계산할 때 사용되며 dict으로 리턴한다.
다른 집계 또는 값과 결합하여 복잡한 집계도 만들 수 있다.
키워드 인수를 사용하여 집계된 키워드를 주석의 이름으로 사용한다. 익명 인수는 집계함수의 이름과 집계되는 모델 필드에 따라 이름이 생성된다. 복합 집계는 익명 인수를 사용할 수 없기 때문에 별칭을 지정해주어야 한다.


Update 데이터 수정

지정된 필드에 대해 업데이트 쿼리를 수행하고(필드값 수정) 일치하는 행 수를 반환한다.
(일부 행에 이미 새 값이있는 경우 업데이트 된 행 수와 같지 않을 수 있음)

update()

여러개의 객체를 한꺼번에 수정할 경우 사용하는 메소드

In [26]: Drink.objects.filter(name="녹차").update(name="그린티")
    ...:
Out[26]: 1

save()

한개의 객체를 수정할 때 사용하는 메소드

In [27]: menu=Menu.objects.get(name="음료")

In [28]: menu.name
Out[28]: '음료'

In [29]: menu.name="드링크"

In [30]: menu.save()

In [31]: menu.name
Out[31]: '드링크'

Delete 데이터 삭제

SQL의 DELETE절
객체를 삭제하기 위해 사용하는 메소드이다.

delete()

QuerySet의 모든 행에 대해 SQL 삭제 쿼리를 수행하고 삭제 된 개체 수와 개체 유형별 삭제 횟수가 있는 dictionary를 반환한다.

In [35]: menu=Menu.objects.all()

In [36]: menu.delete()
Out[36]: (20, {'products.Category': 10, 'products.Menu': 10})

In [37]: menu
Out[37]: <QuerySet []>

queryset API
queryset API reference

profile
Hello!

0개의 댓글