3:django models Making queries 고급 진급-집합 연산
9774 단어 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점 이상) 총수만 포함한다.
첫 번째 질의에서 주석은 필터 앞에 있기 때문에 필터는 주석에 영향을 주지 않습니다.두 번째 조회에서 필터는 주해 전에 있기 때문에 주해 값을 계산할 때 필터는 연산에 참여하는 대상의 범위를 제한한다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django의 질문 및 답변 웹사이트환영 친구, 이것은 우리의 새로운 블로그입니다. 이 블로그에서는 , 과 같은 Question-n-Answer 웹사이트를 만들고 있습니다. 이 웹사이트는 회원가입 및 로그인이 가능합니다. 로그인 후 사용자는 사용자의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.