본문 바로가기
django

QuerySet API

by csue 2021. 4. 27.

What is QuerySet API

django 는 QuerySet API 를 통해 데이터 작업을 위한 포괄적인 method 를 제공한다.
query 란 데이터베이스에 정보를 요청하는 것을 의미한다.

django 에서 제공하는 QuerySet API 를 이용하면, python 으로 작성한 코드를 SQL로 mapping 하여 쿼리셋(queryset) 이라는 자료 형태로 값을 반환할 수 있도록 도와준다.


django document 의 QuerySet API 항목 을 보고 이를 실사용 및 정리해보았다.

Methods that return new QuerySets

method 를 입력하면 해당 method 의 내용을 실행한 후, QuerySet 을 반환하는 methods.

all()

현재 또는 하위 class 의 복사본을 반환한다.

>>> Menu.objects.all()
<QuerySet [<Menu: Menu object (1)>, <Menu: Menu object (2)>, <Menu: Menu object (3)>, <Menu: Menu object (4)>]>

filter(kwargs)

지정된 조회 매개 변수와 일치하는 객체를 포함한 새 QuerySet 을 반환한다.

>>> Menu.objects.filter(id=1)
<QuerySet [<Menu: Menu object (1)>]>

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

exclude(kwargs)

지정된 매개변수와 일치하지 않는 QuerySet 을 반환한다.

>>> Menu.objects.exclude(id=1)
<QuerySet [<Menu: Menu object (2)>, <Menu: Menu object (3)>, <Menu: Menu object (4)>]>

distinct()

SQL query 의 SELECT DISTINCT 와 같은 역할을 수행한다. QuerySet 결과 중에서 중복된 요소를 제거한다.

>>> a = productcolorimages.values('color__name')

>>> a
<QuerySet [{'color__name': 'BLACK'}, {'color__name': 'BLACK'}, {'color__name': 'BLACK'}, {'color__name': 'BLACK'}, {'color__name': 'BLACK'}, {'color__name': 'BLACK'}]>

>>> a.distinct()
<QuerySet [{'color__name': 'BLACK'}]>

values()

QuerySet 을 dictionary 형식으로 반환한다.

*iterable : 한 번에 하나의 member를 반환할 수 있는 object

>>> Menu.objects.values()
<QuerySet [{'id': 1, 'name': '음료'}, {'id': 2, 'name': '푸드'}, {'id': 3, 'name': '상품'}, {'id': 4, 'name': '카드'}]>

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

>>> Menu.objects.exclude(id=1).values()
<QuerySet [{'id': 2, 'name': '푸드'}, {'id': 3, 'name': '상품'}, {'id': 4, 'name': '카드'}]>

values_list()

value 와 유사하나 QuerySet 을 dictionary 가 아닌 tuple 로 반환한다.

>>> Menu.objects.values_list()
<QuerySet [(1, '음료'), (2, '푸드'), (3, '상품'), (4, '카드')]>

>>> Menu.objects.values_list('name')
<QuerySet [('음료',), ('푸드',), ('상품',), ('카드',)]>

select_related & prefetch_related

해당 부분은 아래 게시글에서 좀 더 자세히 설명하려 한다.

2021.04.27 - [django] - select_related & prefetch_related

Methods that do not return QuerySets

QuerySet 이 아닌 다른 것을 반환하는 methods.

get(kwargs)

지정된 함수와 일치하는 객체를 단 하나만 반환한다.
여러개 있다거나 값이 존재하지 않는 경우, error 가 발생한다.

>>> Menu.objects.get(id=1)
<Menu: Menu object (1)>

>>> Menu.objects.get(name="음료")
<Menu: Menu object (1)>

>>> Menu.objects.filter(pk=1).get()
# 값이 여러개일경우 MultipleObjectsReturend
<Menu: Menu object (1)>

create(kwargs)

객체를 만들고 저장하고 난 후 해당 객체를 반환한다.

>>> Menu.objects.create(name="음료수")
<Menu: Menu object (5)> # 4까지 있었는데 5가 추가되었다.

bulk_create()

list 를 데이터베이스에 삽입한다. 아직 저장되지 않은 객체를 담은 list 가 반환된다.

>>> a1 = Menu(name="음료")
>>> a2 = Menu(name="푸드") 
>>> Menu.objects.bulk_create([a1, a2])
[<Menu: Menu object (None)>, <Menu: Menu object (None)>]

count()

일치하는 데이터베이스의 수를 나타내는 정수를 반환한다.

>>> Menu.objects.count()
4

>>> Menu.objects.filter(id=1).count()
1

>>> Menu.objects.values_list('id').count()
4

exists()

QuerySet 에 포함된 경우 True 를 반환하고, 그렇지 않은 경우 False 를 반환한다.

>>> Menu.objects.filter(name="음료").exists()
True
>>> Menu.objects.filter(name="술").exists()
False

update(kwargs)

지정된 field 를 수정하고 수정된 row 의 수를 반환한다.

>>> Menu.objects.filter(id=1).update(name="사탕")
1

delete()

삭제된 객체 수와 객체의 type 을 dictionary 형태로 반환한다.

>>> Menu.objects.filter(id=5).delete()
(1, {'products.Menu': 1})

first()

QuerySet 과 일치하는 첫 번째 객체를 반환하거나, 일치하는 객체가 없는 경우 None 을 반환한다.

>>> Menu.objects.first()
<Menu: Menu object (1)>

last()

first 와 같으나 마지막 객체 혹은 None 을 반환한다.

Field lookups

필드 탐색
filter, exclude, get 등의 method 를 통해 필드에서 필요한 kwargs 를 호출한다.

less / greater / equal than

존재하지 않으면 빈 쿼리셋을 호출한다.

  • l : less
  • g : greater
  • t : than
  • e : equal
>>> User.objects.filter(id__lt=5) # 5보다 작은 id
>>> User.objects.filter(id__lte=5) # 5와 같거나 작은 아이디
>>> User.objects.filter(id__gt=5) # 5보다 큰 아이디

--swith

조건값으로 시작하는 데이터.
존재하지 않으면 빈 쿼리셋을 호출한다.

__startswith : 조건값으로 시작하는 데이터
__endswith : 조건값으로 끝나는 데이터
__contains : 조건값을 포함하는 데이터

__istartswith : 앞에 i를 붙이면 대소문자를 구분하지 않는다

>>> Drink.objects.filter(name__startswith="피치")

Q objects

연산자를 이용한 조건을 걸어 데이터를 가져올 수 있다. filter, exclude, get 과 같은 조회함수와도 함께 사용할 수 있다.
존재하지 않으면 빈 쿼리셋을 호출한다.

  • ~Q : not Q
  • & and
  • | or
>>> from django.db.models import Q
>>> Drink.objects.filter(Q(name__startswith='사이다') & ~Q(category_id__lte=5))
# 사이다라는 이름으로 시작하고 카테고리 아이디가 5와 같거나 작은 objects

Aggregation functions

집계함수

annotate()

Methods that return new QuerySets
필드 하나를 만들고 그 곳에 내용을 채운다.

>>> from django.db.models import Count

>>> a = Drink.objects.annotate(Count('name'))
>>> a[0]
<Drink: Drink object (1)>
>>> a[10]
<Drink: Drink object (11)>
>>> a[10].name
'더블 에스프레소 칩 프라푸치노'

이 경우는, Drink.objects 에서 name 이라는 키를 가진 객체를 센 것을 a 라는 필드에 넣었다.
값이 존재하지 않는 경우, 아래처럼 error 가 발생한다.

>>> a[48]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/sua/desktop/sua/enter/Users/sua/envs/westarbucks/lib/python3.7/site-packages/django/db/models/query.py", line 325, in __getitem__
    return qs._result_cache[0]
IndexError: list index out of range
>>> a[47]
<Drink: Drink object (48)>

aggregate()

Methods that do not return QuerySets
테이블의 특정 컬럼 전체로부터 하나의 값을 집계하여 반환하는 함수로, Count, Sum, Avg, Max, Min 등이 있다.

>>> from django.db.models import Avg
>>> Drink.objects.all().aggregate(Avg('category_id'))
{'catogory_id__avg' : 11}

# 출력시 dict... 키를 변경하여 출력하는것도 가능하다.
>>> Drink.objects.all().aggregate(a=Avg('category_id'))
{'a' : 11}

'django' 카테고리의 다른 글

select_related & prefetch_related  (0) 2021.04.27
django  (0) 2021.04.27