[Django] QuerySet 메소드 + 더보기

황인용·2020년 8월 30일
5

Django

목록 보기
10/13
post-custom-banner

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

idname(이름)
1이작가
2여작가
3김작가
4천작가
5황작가
......

Publisher(출판사) table

idname(이름)
1A출판
2B출판
3C출판
4D출판
5E출판
......

Book(책) table

idname(이름)pages(페이지수)price(가격)rating(평점)author_id(저자_id)publisher_id(출판사_id)pubdate(출시날짜)
1A-1책30035.005.0112019-01-04
2B-1책40040.004.0122019-03-01
3C-1책20025.005.0332019-05-24
4D-1책10015.003.0342020-03-14
5E-1책80055.504.0252020-06-24
........................

Store(매장) table

idname(이름)book_id(책_id)
1A매장1
2B매장1
3C매장1
4C매장2
5C매장3
6D매장4
7D매장5
8E매장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
김작가

참고

profile
dev_pang의 pang.log
post-custom-banner

0개의 댓글