API란?
Application Programming Interface의 약자로 어플리케이션에서 시스템의 기능을 제어할 수 있도록 만든 인터페이스를 말한다.
즉, 어떤 기능을 쉽게 사용할 수 있도록 만든 체계라고 할 수 있다.
Queryset
Queryset은 Django Model의 데이터가 담겨있는 목록으로 파이썬의 리스트와 비슷한 형태를 가지고 있다.
우리는 이러한 Queryset을 얻기 위해서 'objects'를 이용한다. 'objects'는 Model Manager.라고 하는데 Model과 데이터베이스
간에 연산을 수행하는 역할을 한다. 이 'objects'를 통해 데이터베이스와 연산해서 얻은 여러 모델 데이터가 담겨있는 것이 Queryset이다.
Queryset API
Queryset은 데이터베이스로 부터 가져온 여러개의 model 데이터이다.
원하는 조건에 맞게 사용할 수 있으면 된다.
API설명예시
Queryset을 반환하는 API
all() | 해당 모델 테이블의 모든 데이터 조회 | Post.objects.all() |
filter() | 특정 조건에 맞는 모든 데이터 조회 | Post.objects.filter(content__contains='coke') |
exclude() | 특정 조건을 제외한 모든 데이터 조회 | Post.objects.exclude(title__contains='code') |
order_by() | 특정 조건으로 정렬된 데이터 조회 (-를 붙이면 오름차순으로 정렬) |
Post.objects.order_by('-dt_created') |
values() | Queryset에 있는 모든 모델 데이터의 정보를 사전형으로 갖는 리스트 반환 | Post.objects.all().values() |
하나의 객체를 반환하는 API
API설명예시
get() | 조건에 맞는 하나의 데이터 조회 | Post.objects.get(id=1) |
create() | 하나의 데이터를 생성하고 해당 모델 데이터를 반환 | Post.objects.create(title='Learning Django', context='Codeit Django') |
get_or_create() | 조건에 맞는 데이터를 조회하고 해당 데이터가 없다면 새로 생성 후 생성된 모델 데이터를 반환 | Post.objects.get_or_create(title='Learning Python', context='It's good’) |
latest() | 주어진 필드 기준으로 가장 최신의 모델 데이터를 반환 | Post.objects.latest('dt_created') |
first() | 쿼리셋의 가장 첫번째 모델 데이터를 반환, 정렬하지 않은 쿼리셋이라면 pk를 기준으로 정렬 후 반환, 만약 데이터가 없다면 None | Post.objects.order_by('title').first() |
last() | 연산된 쿼리셋의 가장 가지막 모델 데이터를 반환, 만약 데이터가 없다면 None |
Post.objects.order_by('title').last() |
그 외 API
exists() | 연산된 쿼리셋에 데이터가 있다면 True 반환 | Post.objects.get(pk=812).exists() |
count() | 쿼리셋의 데이터 개수를 정수로 반환 | Post.objects.all().count() |
update() | 데이터를 수정할 때 사용 (여러 데이터 또는 여러 필드를 한 번에 수정 가능), 수정된 데이터의 개수를 정수로 반환 |
Post.objects.filter('dt_created'__yeaer=2021).update(context='codeit') → 생성일이 2021년인 모든 포스트 데이터들의 context를 'codeit'으로 바꾸고 변경된 데이터의 개수를 리턴 |
delete() | 데이터를 삭제할 때 사용 | post = Post.objects.get(pk=1) post.delete() |
필드 옵션 조건 (Field Lookups)
Queryset 연산을 할 때 사용할 수 있는 여러 필드 조건 옵션이다. 필드명 뒤에 _ _ 를 쓰고 사용할 옵션 인자를 적어주면 된다.
공식문서
https://docs.djangoproject.com/en/2.2/ref/models/querysets/#field-lookups
QuerySet API reference | Django documentation | Django
Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate
docs.djangoproject.com
lookup설명예시
__contains | 대소문자를 구분하여 문자열 포함 여부 확인 | Post.objects.get(title__contains='Codeit') |
__icontains | 대소문자를 구분하여 문자열 불포함 여부 확인 | Post.objects.get(title__icontains='Codeit') |
__in | 반복 가능한 객체 안에서의 포함 여부를 확인 | Post.objects.filter(id__in=[1, 2, 3]) |
__gt | 초과 여부 확인 (Greater than) | Post.objects.filter(id__gt=4) |
__gte | 이상 여부 확인 (Greater than or equal to) | Post.objects.get(id__gte=4) |
__lt | 미만 여부 확인 (Less than) | Post.objects.get(id__lt=4) |
__lte | 이하 여부 확인 (Less than or equal to) | Post.objects.get(id__lte=4) |
__startswith | 대소문자를 구분하여 해당 문자열로 시작하는지 여부 확인 | Post.objects.filter(title__startswith='code') |
__istatswith | 대소문자를 구분하여 해당 문자열로 시작하지 않는지 여부 확인 | Post.objects.filter(context__istartswith='code') |
__endswith | 대소문자를 구분하여 해당 문자열로 끝나는지 여부 확인 | Post.objects.filter(title__endswith='code') |
__iendswith | 대소문자를 구분하여 해당 문자열로 끝나지 않는지 여부 확인 | Post.objects.filter(title_iendswith='code') |
__range | range로 제시하는 범위 내에 포함되는지 확인 (시작과 끝 범위 모두 포함) |
import datetime start_date = datetime.date(2021, 1, 1) end_date = datetime.date(2021, 3, 1) Post.objects.filter (dt_created__range=(start_date, end_date)) |
__isnull | 해당 필드가 Null 인지 여부를 확인 | Post.objects.filter(context__isnull=True) |
Lazy Evaluation (지연 연산)
위에서 작성한 Django의 모든 Query 연산은 병합(Chain)이 가능하다. 예를 들어, Post 중에 id가 10 이상이면서 제목에 '****'이
들어가는 모든 데이터 중 가장 마지막에 작성된 데이터를 가져오고 싶다고 한다면,
Post.objects.filter(id__gte=10, content__contains='****').order_by('-dt_created').last()
이렇게 하나의 Query 연산에 여러개를 체인으로 엮어서 구현하는 것이 코드를 짧게 작성하니 좋다고 생각할 수 있지만 너무 많은
연산을 묶는 것은 지양해야 한다. 모든 코드는 항상 명확하게 작성해야 한다. 위처럼 하나의 Query에서 여러 연산을 수행 하도록
하는 것은 가독성을 매우 떨어뜨리므로 복잡한 Query를 한 번에 체인으로 묶는 것은 피하는 것이 좋다. 대신 아래처럼 작성한다.
post_data = Post.objects.filter(id__gte=10, content__contains='codeit')
post_data = post_data.order_by('dt_created')
post_data = post_data.last()
그런데 이렇게 여러 번에 나누어서 작상하면 코드가 훨씬 느려지는 것은 아닐까? 아님
Django의 Query는 기본적으로 지연 연산을 지원한다. 지연 연산이란 실제로 데이터가 필요하기 전 까지 Query 연산을 수행하지
않고 지연(Lazy)되는 것을 말한다. 우리가 위에서 처럼 모두 체인으로 묶어서 한 줄로 적는 것과 아래처럼 여러 줄로 나누어 적는 것이
결국 같은 시점에 같은 연산을 수행하게 되는 것이다. 그래서 우리는 한 줄에 모든 Query 연산과 기능을 작성하는 것 대신 여러 줄에
얼마든지 Query 를 연결해서 작성할 수 있고, 이것은 가독성을 향상시키고 유지보수에 편리하게 한다.
'Django' 카테고리의 다른 글
[Django] CSRF 방지 (0) | 2021.12.14 |
---|---|
[Django] HTML Form (0) | 2021.12.11 |
[Django 기초] CRUD (0) | 2021.12.06 |
[Django 기초] 마이그레이션(Migration) (0) | 2021.12.06 |
[Django 기초] Model의 Field (0) | 2021.12.06 |