Example Model
class Author(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
class Publisher(models.Model):
name = models.CharField(max_length=300)
class Book(models.Model):
name = models.CharField(max_length=300)
pages = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
rating = models.FloatField()
author = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
pubdate = models.DateField()
class Store(models.Model):
name = models.CharField(max_length=300)
books = models.ManyToManyField(Book)
Author(저자) table
id | name(이름) |
---|
1 | 이작가 |
2 | 여작가 |
3 | 김작가 |
4 | 천작가 |
5 | 황작가 |
... | ... |
Publisher(출판사) table
id | name(이름) |
---|
1 | A출판 |
2 | B출판 |
3 | C출판 |
4 | D출판 |
5 | E출판 |
... | ... |
Book(책) table
id | name(이름) | pages(페이지수) | price(가격) | rating(평점) | author_id(저자_id) | publisher_id(출판사_id) | pubdate(출시날짜) |
---|
1 | A-1책 | 300 | 35.00 | 5.0 | 1 | 1 | 2019-01-04 |
2 | B-1책 | 400 | 40.00 | 4.0 | 1 | 2 | 2019-03-01 |
3 | C-1책 | 200 | 25.00 | 5.0 | 3 | 3 | 2019-05-24 |
4 | D-1책 | 100 | 15.00 | 3.0 | 3 | 4 | 2020-03-14 |
5 | E-1책 | 800 | 55.50 | 4.0 | 2 | 5 | 2020-06-24 |
... | ... | ... | ... | ... | ... | ... | ... |
Store(매장) table
id | name(이름) | book_id(책_id) |
---|
1 | A매장 | 1 |
2 | B매장 | 1 |
3 | C매장 | 1 |
4 | C매장 | 2 |
5 | C매장 | 3 |
6 | D매장 | 4 |
7 | D매장 | 5 |
8 | E매장 | 1 |
... | ... | ... |
order_by()
- queryset 결과를 지정하는 매개변수의 조건으로 정렬하는 메소드
- 기본 지정된 컬럼 기준 오름차순 정렬
- 내림차순 정렬 시
-
붙여서 매개변수로 지정
- e.g.
id
오름차순 기준 정렬 : order_by('id')
- e.g.
id
내림차순 기준 정렬 : order_by('-id')
>>> Author = Author.objects.all().order_by('-id')
<QuerySet [<Author: Author object (5)>, <Author: Author object (4)>, <Author: Author object (3)>, <Author: Author object (2)>, <Author: Author object (1)>]>
slicing(슬라이싱)
- queryset 결과를 특정 지정 인덱스 기준으로 slicing(슬라이싱) 하는 방법
- iterable한 결과에서 슬라이싱 가능
- 역순 슬라이싱은 지원하지 않는다
- pagination 시 사용많이 함
>>> Author = Author.objects.all()[:3]
<QuerySet [<Author: Author object (1)>, <Author: Author object (2)>, <Author: Author object (3)>]>
>>> author = Author.objects.all()[3:]
<QuerySet [<Author: Author object (3)>, <Author: Author object (4)>, <Author: Author object (5)>]>
aggregate()
- 사전적의미로 '총액', '합계'라는 의미로 집계함수모듈를 사용시 사용하는 메소드
- 즉, 집계함수모듈 django의
Avg
, Max
, Min
, Count
, SUM
등을 사용할 때 사용하는 메소드
- 위 집계함수를 매개변수로 지정하여 사용
- 결과는 dictionary(딕셔너리)형태로 반환
annotate()
- 사전적의미로 '주석을 달다'라는 의미로
aggregate()
는 queryset의 전체row에 대한 집계함수를 반환한 반면, annotate()
는 각 컬럼별 주석을 달고 집계함수를 사용하여 반환한다
- 즉, SQL의
GROUP BY
와 같은 의미로, queryset결과를 컬럼별 group by
하여 반환한다
- 결과는 queryset(쿼리셋)형태로 반환
avg
- queryset 결과에서 특정 컬럼기준 평균값을 구할 때 사용하는 매개변수
- django.db.models의
Avg
모듈을 가져와야 함
- Alias처럼 결과의 key값을 변경 가능
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}
>>> Book.objects.all().aggregate(average_price=Avg('price'))
{'average_price': 34.35}
Max, Min
- queryset 결과에서 특정 컬럼기준 최대값 또는 최소값을 구할 때 사용하는 매개변수
- django.db.models의
Max
, Min
모듈을 가져와야 함
- Alias처럼 결과의 key값을 변경 가능
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Max('price'), Min('price'))
{'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
>>> Book.objects.aggregate(max_price=Max('price'), min_price=Min('price'))
{'max_price': Decimal('81.20'), 'min_price': Decimal('12.99')}
Count
- queryset 결과에서 특정 컬럼기준 count를 구할 때 사용하는 매개변수
- django.db.models의
Count
모듈을 가져와야 함
- Alias처럼 결과의 key값을 변경 가능
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count('authors'))
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1
filter()와 exclude() 추가
aggregate()
앞에 queryset을 filter()
또는 exclude()
를 추가하여 결과를 반환할 수 있다
aggregate()
뒤에 filter()
또는 exclude()
적용도 가능
aggregate()
앞에 붙느냐, 뒤에 붙느냐에 따라 queryset 결과가 다르게 나옴
>>> from django.db.models import Avg, Count
>>> Book.objects.filter(name__startswith="Django").aggregate(Avg('price'))
>>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors'))
name__startswith="Django"
에서 startswith는 단어의 시작 string을 조건
aggregate()
경우, 책 이름이 "Django"로 시작하는 책들의 평균 가격 값을 반환
annotate()
경우, 책 이름이 "Django"로 시작하고, 책들의 각 저자의 수로 정렬한 값을 반환
- QuerySet문자열조건참고
>>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1)
num_authors__gt
에서 gt는 부등식의 초과
라는 의미
- 위 filter의 매개변수는 '저자수가 1보다 큰'이라는 조건
- 따라서, 책들을 저자의 수로 정렬한 후, 저자의 수가 1보다 큰 queryset만 반환
- QuerySet부등식조건참고
distinct()
- queryset 결과에서 중복되는 값을 제거하고 고유값만 반환하는데 사용하는 메소드
- SQL의
SELECT DISTINCT
절
>>> book = Book.objects.distinct('author')
>>> book
<QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>]>
>>> book[0].author.name
이작가
>>> book[1].author.name
여작가
>>> book[2].author.name
김작가
참고