장고 crud를 진행하면서 쿼리셋 메소드에 대해 좀 더 배워야겠다는 생각이 들었다. 지금까지는 all
, create
, get
, filter
메소드 정도만 많이 사용했는데, 다른 메소드들도 장고쉘에서 사용해보았다. 지난번 주인과 강아지 과제로 쿼리셋 메소드를 사용해보았다.
Owner.objects.get_or_create(**kwargs)
return (object, Boolean Tag)
객체가 데이터베이스에 존재하지 않다면 새로운 객체를 생성하고 그 객체와 True를 반환한다. 존재하면 존재하는 객체와 False를 반환한다.
튜플 형태로 반환한다.
지금까지는 객체를 생성할 때 create
를 사용해왔다. get_or_create
는 중복되는 객체가 있는지 먼저 체크한 후 생성한다.
Owner.objects.get_or_create(name="키", ~)
이미 id 1번에 존재하는 데이터이므로 False 를 반환한다.
Owner.objects.get_or_create(name="태연", email="ty@email.com", age=20)
데이터베이스에 없기 때문에 (<Owner: Owner object (8)>, True)
을 반환한다. 데이터베이스에 접속하면 id 8번으로 새로운 객체를 생성한 것을 확인할 수 있다.
Owner.objects.update_or_create(**kwargs, default={})
return (object, Boolean Tag)
keyword arguments
에 해당하는 객체가 없다면, 새로운 객체를 생성하고 True를 반환한다. 객체가 있다면 default의 인자를 업데이트하고 False를 반환한다.
좀 전에 생성한 Owner id가 8번인 객체를 예로 들어 알아보자.
Owner.objects.update_or_create(name="태연", email="ty@email.com", age=10, default={"name" : "지연"})
Owner.objects.update_or_create(name="태연", email="ty@email.com", age=10, default={"name" : "지연"})
from django.db.models import Avg, Max, Min
Owner.objects.all().aggregate(Avg("age"))
필드 전체를 통합하여 합계, 평균, 최대값, 최소값 등을 구할 때 사용한다.
계산은 장고 모듈을 불러와서 사용할 수 있다.
딕셔너리 형태로 반환한다.
Owner
의 평균 나이를 계산할 수 있다. 반환된 키 값은 장고에서 자동으로 생성해준다. 다른 이름으로 바꾸고 싶다면 (average=Avg("age"))
와 같이 원하는 이름을 작성하면 된다.
이전에는 관계가 있는 두 모델에 대해 조회를 할 때 정참조와 역참조를 생각하며 메소드를 작성했다. 정참조인 Dog
은 위와 같이 한 줄로 작성하여 Owner
의 이름을 출력할 수 있다. 역참조의 경우는 자신을 참조하는 객체를 모르기 때문에 attribute error 가 발생한다. 대신 _set
과 for 문을 사용해 Dog
이름을 출력할 수 있다.
이중밑줄 __
을 사용하면 정참조와 역참조와 무관하게 작용한다.
get/filter(관계되는 객체__필드명 = 필드값)
Actor
와 Movie
와 같은 M2M 관계에서도 가능하다.
Actor.objects.filter(movie__title="돈")
영화 '돈'에 출연한 배우를 조회해준다.
Movie.objects.filter(actor__first_name="준열")
배우 '준열'이 출현한 영화들을 조회해준다.
중간테이블로 연결된 M2M 관계와 같이 여러 모델이 연결된 관계에 대해서도 필터링할 수 있다. 중간테이블을 먼저 쓴 다음 연결될 모델과 필드명을 적어준다.
Actor.objects.filter(actormovie__movie__title="0title")
field__lookuptype = value
lookup 옵션은 관계된 다른 모델의 쿼리셋을 가져올 수 있다. filter, exclude, get 메소드에서 사용할 수 있다.
lt / gt / lte / gte : ~보다 작다 / ~보다 크다 / ~보다 작거나 같다 / ~보다 크거나 같다
예) model.objects.filter(id__lt=5)
id가 5보다 작은 데이터를 검색한다.
in : 반복가능한 타입을 넣어준다. (리스트, 튜플, 쿼리셋) 문자열도 가능하다.
예) model.objects.filter(id__in[1,2,4])
id 1,2,4 중 존재하는 데이터만 반환한다. 아무것도 없으면 빈 쿼리셋을 반환한다.
year, month, day : 연도, 월, 일 검색
예) model.objects.filter(published_date__year=2019)
published_date가 2019년인 데이터를 검색한다.
model.objects.filter(published_date__year__gt=2019)
published_date가 2019년 이후의 데이터를 검색한다.
isnull : null인 데이터 검색
예) model.objects.filter(name__isnull=True)
contains / icontains : 지정값이 포함된 데이터를 검색 / 대소문자 구분 x
예) model.objects.filter(name__contains="김")
name에 "김"이 포함된 데이터를 검색한다.
startswith / endswith / istartswith, iendswith : 지정값으로 시작하는 데이터를 검색 / 지정값으로 끝나는 데이터 검색 / 대소문자 구분 x
exact / iexact : 지정값과 일치하는 데이터 검색 / 대소문자 구분 x
range : 해당 범위 안의 데이터를 검색한다. 문자, 숫자, 날짜 등의 범위로 지정할 수 있다.
Owner.objects.filter(age__lt=20)
Owner
의 나이가 20살 미만인 데이터를 검색하여 쿼리셋으로 반환해준다.
Owner.objects.filter(dog__age__gt=4)
Dog
모델 자체에서 필터링할 수 있지만, Dog
의 나이가 4살 초과인 데이터를 검색할 때 이런 식으로도 표현이 가능하다.