3:django models Making queries 고급 진급-집합 연산

9774 단어 django
앞의 문장django models Making queries에서 우리는django가 자주 사용하는 검색 데이터베이스 내용을 언급했다.
다음은 더욱 고급스러운 검색 집합 연산을 살펴보겠습니다.
저희가 쓸 모형이에요.
class Author(models.Model):

   name = models.CharField(max_length=100)

   age = models.IntegerField()

   friends = models.ManyToManyField('self', blank=True)



class Publisher(models.Model):

   name = models.CharField(max_length=300)

   num_awards = models.IntegerField()



class Book(models.Model):

   isbn = models.CharField(max_length=9)

   name = models.CharField(max_length=300)

   pages = models.IntegerField()

   price = models.DecimalField(max_digits=10, decimal_places=2)

   rating = models.FloatField()

   authors = models.ManyToManyField(Author)

   publisher = models.ForeignKey(Publisher)

   pubdate = models.DateField()



class Store(models.Model):

   name = models.CharField(max_length=300)

   books = models.ManyToManyField(Book)

 
고급 집합 연산의 예를 직접 보도록 하겠습니다.
# Total number of books.

>>> Book.objects.count()

2452



# Total number of books with publisher=BaloneyPress

>>> Book.objects.filter(publisher__name='BaloneyPress').count()

73



# Average price across all books.

>>> from django.db.models import Avg

>>> Book.objects.all().aggregate(Avg('price'))

{'price__avg': 34.35}



# Max price across all books.

>>> from django.db.models import Max

>>> Book.objects.all().aggregate(Max('price'))

{'price__max': Decimal('81.20')}



# Each publisher, each with a count of books as a "num_books" attribute.

>>> from django.db.models import Count

>>> pubs = Publisher.objects.annotate(num_books=Count('book'))

>>> pubs

[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]

>>> pubs[0].num_books

73



# The top 5 publishers, in order by number of books.

>>> from django.db.models import Count

>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]

>>> pubs[0].num_books

1323

 
aggregate(영문 본뜻: a sum total of many heterogenous things taken together, 합계, 집합체, 총계)
annotate(영문 본뜻: add explanatory notes to or supply with critical comments, 중국어 해석: 주석, 주석을 달거나 주석을 달다)
위에서 제시한 예와 결합하면 우리는 이렇게 총결할 수 있을 것 같다
aggregate는 우리가 흥미를 느끼는 어떤 열에 대해 약간의 조작을 하고, 되돌아오는 것은 사전이다
annotate는 하나의queryset을 되돌려줍니다. 그리고 이queryset은 우리가 필요로 하는 추가 필드가 있습니다.
계속해서 annotate의 예를 보도록 하겠습니다.
# Build an annotated queryset

>>> q = Book.objects.annotate(Count('authors'))

# Interrogate the first object in the queryset

>>> q[0]

<Book: The Definitive Guide to Django>

>>> q[0].authors__count

2

# Interrogate the second object in the queryset

>>> q[1]

<Book: Practical Django Projects>

>>> q[1].authors__count

1

 
이제 좀 더 고급스러운 조작을 해보도록 하겠습니다.
1:각store의 가격 범위를 찾아라. 범위의 결과가store를 포함하려면 annotate를 사용해야 한다.
>>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))

 
만일 당신이 모든store의 가격 범위를 알고 싶을 뿐이라면, 당신은aggregate를 사용해야 한다
 Store.objects.aggregate(min_price=Min('books__price'), max_price=Max('books__price'))

 
그룹 조회values()
values () 를 사용하면 조회 전후에 데이터를 그룹화할 수 있습니다
마지막으로 저희가 조회 순서에 대한 예를 몇 가지 말씀드릴게요.
1:annotate와values의 순서
>>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))

>>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')

 
첫 번째 줄의 조회를 할 때 먼저 작가를 그룹으로 나누고(같은 이름의 작가의 책은 한 그룹으로 분류되며) 각 작가의 평균 순위로 돌아간다.
두 번째 줄의 조회는 모든 작가에게average 를 생성합니다.rating, 그리고 모든 author의name와average 만 출력합니다.rating
2:Filter와 annotate의 순서
>>> Publisher.objects.annotate(num_books=Count('book')).filter(book__rating__gt=3.0)

>>> Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count('book'))

 
두 조회 모두 적어도 좋은 책 한 권 (평점이 3점 이상) 을 출판한 출판사의 목록을 되돌려 주었다.
그러나 첫 번째 조회의 주석은 출판사가 발행한 모든 도서의 총수를 포함한다.
두 번째 조회의 주해는 좋은 책을 출판한 출판사의 발행된 좋은 책(평점 3점 이상) 총수만 포함한다.
첫 번째 질의에서 주석은 필터 앞에 있기 때문에 필터는 주석에 영향을 주지 않습니다.두 번째 조회에서 필터는 주해 전에 있기 때문에 주해 값을 계산할 때 필터는 연산에 참여하는 대상의 범위를 제한한다

좋은 웹페이지 즐겨찾기