Django Aggregation 집선
9040 단어 django
다음 모델의 경우
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
class Publisher(models.Model):
name = models.CharField(max_length=300)
num_awards = models.IntegerField()
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()
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)
registered_users = models.PositiveIntegerField()
빠른 이해
# books .
>>> Book.objects.count()
2452
# Total number of books with publisher=BaloneyPress
>>> Book.objects.filter(publisher__name='BaloneyPress').count()
73
# books price.
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}
# books price.
>>> from django.db.models import Max
>>> Book.objects.all().aggregate(Max('price'))
{'price__max': Decimal('81.20')}
# All the following queries involve traversing the Book<->Publisher
# many-to-many relationship backward
# publisher num_books , pulisher book .
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
>>> pubs[0].num_books
73
# num_book .
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323
Generating aggregates over a QuerySet 모음 생성
Django는 집합을 생성하는 두 가지 방법이 있습니다.첫 번째 방법은 전체 QuerySet에 집합 값을 생성하는 것입니다. 예를 들어 모든 책의 price 평균 값을 생성하는 것입니다.
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}
다음과 같이 요약할 수 있습니다.
>>> Book.objects.aggregate(Avg('price'))
{'price__avg': 34.35}
함수aggregate()의 매개 변수는 일련의 집합 함수aggregate functions:
Avg
평균값 반환
Count class Count(field, distinct=False)
카운트를 반환합니다.distinct=True 매개 변수가 있으면 unique의 객체 수를 반환합니다.
Max
최대값 반환
Min
최소값을 반환합니다.
StdDev class StdDev(field, sample=False) 표준 편차 반환
Sample 매개 변수가 있습니다.
기본적으로 Sample=False는 전체 표준 편차를 되돌려줍니다. Sample=True라면 샘플 표준 편차를 되돌려줍니다.
Sum
반환 총액
Variance class Variance(field, sample=False) 반환 분산
기본적으로 전체 방차를 되돌려주는 매개 변수 Sample이 있습니다. Sample이True로 설정되었을 때 샘플 방차를 되돌려줍니다.
aggregate () 방법이 호출되었을 때 키 값을 사전으로 되돌려줍니다. 키의 이름을 지정할 수 있습니다.
>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}
만약 여러 개의 집합을 만들고 싶다면, 다른 매개 변수를 추가하기만 하면 된다.그래서 만약에 우리가 모든 책의 최고와 최저 가격을 알고 싶다면:
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
쿼리 세트의 각 객체에 대한 집계 값 생성Generating aggregates for each item in a QuerySet
이것은 집합 값을 생성하는 두 번째 방법이다.예를 들어 너는 책마다 몇 명의 작가가 있는지 검색해야 한다.책과 author는 manytomany의 관계로 책마다 이런 관계를 정리할 수 있다.
각 객체의 요약은 다음과 같은 방법으로 annotate()를 생성할 수 있습니다.
# annotate QuerySet
>>> 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[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1
생성된 속성의 이름을 지정할 수도 있습니다.
>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1
aggregate () 와 달리 annotate () 의 출력은QuerySet입니다.
통합 클러스터 Joins and aggregates
지금까지 저희가 조회를 모은field는 모두 저희가 조회하고자 하는 모델에 속했고 다른 모델의field로 조회를 모을 수 있습니다. 예를 들어 다음과 같습니다.
>>> from django.db.models import Max, Min
>>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))
이렇게 하면 모든 스토어에서 책의 가격 범위를 조회할 수 있다
연결 체인의 깊이는 다음과 같습니다.
>>> Store.objects.aggregate(youngest_age=Min('books__authors__age'))
역관계Following relationships backwards
책갈피를 사용하여 publisher를 반대로 질의하려면 다음과 같이 하십시오.
>>> from django.db.models import Count, Min, Sum, Avg
>>> Publisher.objects.annotate(Count('book'))
되돌아오는 QuerySet의 모든publisher는 속성bookcount.
가장 오래 출판된 책의 출판 날짜를 조회하다.
>>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate'))
각 저자가 쓴 책의 총 페이지 수를 조회하려면 다음과 같이 하십시오.
>>> Author.objects.annotate(total_pages=Sum('book__pages'))
모든 저자가 쓴 책의 평균 rating 조회:
>>> Author.objects.aggregate(average_rating=Avg('book__rating'))
집계 및 기타 쿼리 세트 작업Aggregations and other QuerySet clauses
filter() and exclude()
집합은 Filter 및 exclude와 함께 사용할 수 있습니다.
>>> from django.db.models import Count, Avg
>>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors'))
>>> Book.objects.filter(name__startswith="Django").aggregate(Avg('price'))
집계 값을 기준으로 필터링할 수 있습니다.
>>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1)
annotate () 와 Filter () 종문을 포함하는 복잡한 검색어를 작성할 때QuerySet에 작용하는 종문의 순서에 따라 의미가 다르다는 것을 주의해야 한다.
>>> 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점 이상) 총수만 포함한다.첫 번째 질의에서 주석은 필터 앞에 있기 때문에 필터는 주석에 영향을 주지 않습니다.두 번째 조회에서 필터는 주해 전에 있기 때문에 주해 값을 계산할 때 필터는 연산에 참여하는 대상의 범위를 제한한다
order_by()
집계 값을 기준으로 정렬할 수 있습니다.
>>> Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')
values()
일반적으로 주해 annotate는 모든 대상에 추가되며, 주해 작업을 수행한 조회 집합QuerySet이 되돌아오는 결과에 모든 대상에 주해 값이 추가됩니다.그러나values () 종문을 사용하면 결과의 범위를 제한하고 주석에 값을 부여하는 방법은 완전히 달라집니다.원시적인QuerySet 반환 결과에 모든 대상에 주석을 추가하는 것이 아니라,values () 문장에 정의된 필드 조합에 따라 선결과의 유일한 그룹을 나누고, 그룹마다 주석값을 산출합니다. 이 주석값은 그룹의 모든 구성원에 따라 계산됩니다.
>>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))
이러한 쓰기 방법에서QuerySet은name에 따라 조합되며, 모든 unique name의 집합 값을 되돌려줍니다.만약 두 작가가 같은 이름을 가지고 있다면, 이 두 작가는 하나의 계산으로 여겨져 그들의 책과 함께 모일 것이다.
>>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')
위치가 바뀌면 모든 author에averagerating, 그리고 모든 author의name와average 만 출력합니다.rating.
기본 정렬에서는 다음과 같은 집합을 사용합니다.
from django.db import models
class Item(models.Model):
name = models.CharField(max_length=10)
data = models.IntegerField()
class Meta:
ordering = ["name"]
중복되지 않은 데이터 값이 나타나는 횟수를 알고 싶으면 다음과 같이 쓸 수 있습니다.
# Warning:
Item.objects.values("data").annotate(Count("id"))
이 부분의 코드는 공통된 데이터 값을 사용하여 Item 대상을 그룹화한 다음 그룹마다 id 값의 총수를 얻으려고 합니다.하지만 위에서 그렇게 하는 것은 통하지 않는다.기본 정렬 항목의name도 하나의 그룹 항목이기 때문에, 이 검색은 중복이 아닌 (data,name) 에 따라 그룹을 나눈다. 이것은 당신이 원하던 결과가 아니다.따라서 기본 정렬의 영향을 제거하려면 다음과 같이 써야 합니다.
Item.objects.values("data").annotate(Count("id")).order_by()
Aggregating annotations
또한 annotation 결과에 따라 집합 값을 생성할 수 있다. 예를 들어 책마다 평균 몇 명의 저자가 있는지 계산할 수 있다.
>>> from django.db.models import Count, Avg
>>> Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors'))
{'num_authors__avg': 1.66}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django의 질문 및 답변 웹사이트환영 친구, 이것은 우리의 새로운 블로그입니다. 이 블로그에서는 , 과 같은 Question-n-Answer 웹사이트를 만들고 있습니다. 이 웹사이트는 회원가입 및 로그인이 가능합니다. 로그인 후 사용자는 사용자의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.