본문 바로가기
Django

[Django] Model API

by dio-han 2021. 12. 10.

 

 

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