def test_annotate_values_list(self): books = Book.objects.filter(pk=1).annotate( mean_age=Avg("authors__age")).values_list("pk", "isbn", "mean_age") self.assertEqual(list(books), [ (1, "159059725", 34.5), ]) books = Book.objects.filter(pk=1).annotate( mean_age=Avg("authors__age")).values_list("isbn") self.assertEqual(list(books), [('159059725', )]) books = Book.objects.filter(pk=1).annotate( mean_age=Avg("authors__age")).values_list("mean_age") self.assertEqual(list(books), [(34.5, )]) books = Book.objects.filter(pk=1).annotate( mean_age=Avg("authors__age")).values_list("mean_age", flat=True) self.assertEqual(list(books), [34.5]) books = Book.objects.values_list("price").annotate( count=Count("price")).order_by("-count", "price") self.assertEqual(list(books), [ (Decimal("29.69"), 2), (Decimal('23.09'), 1), (Decimal('30'), 1), (Decimal('75'), 1), (Decimal('82.8'), 1), ])
def test_only_condition_with_remote_fk_join(self): publishers = Publisher.objects.annotate( mean_price=Avg('book__price', only=Q(book__price__gte=30)), mean_rating=Avg('book__rating', only=Q(book__price__gte=0))) p = publishers.get(pk=1) self.assertEqual(p.mean_price, 30.0) self.assertEqual(p.mean_rating, 4.25)
def test_multiple_aggregates(self): vals = Author.objects.aggregate(Sum("age"), Avg("age")) self.assertEqual(vals, { "age__sum": 337, "age__avg": Approximate(37.4, places=1) }) vals = Author.objects.aggregate(Sum("age", only=Q(age__gt=29)), Avg("age")) self.assertEqual(vals, { "age__sum": 254, "age__avg": Approximate(37.4, places=1) })
def test_relabel_aliases(self): # Test relabel_aliases excluded_authors = Author.objects.annotate( book_rating=Min('book__rating', only=Q(pk__gte=1))) excluded_authors = excluded_authors.filter(book_rating__lt=0) books = Book.objects.exclude(authors__in=excluded_authors).annotate( mean_age=Avg('authors__age')) b = books.get(pk=1) self.assertEqual(b.mean_age, 34.5)
def test_more_aggregation(self): a = Author.objects.get(name__contains='Norvig') b = Book.objects.get(name__contains='Done Right') b.authors.add(a) b.save() vals = Book.objects.annotate(num_authors=Count("authors__id")).filter( authors__name__contains="Norvig", num_authors__gt=1).aggregate(Avg("rating")) self.assertEqual(vals, {"rating__avg": 4.25})
def test_single_aggregate(self): vals = Author.objects.aggregate(Avg("age")) self.assertEqual(vals, {"age__avg": Approximate(37.4, places=1)}) vals = Author.objects.aggregate(Sum("age", only=Q(age__gt=29))) self.assertEqual(vals, {"age__sum": 254}) vals = Author.objects.extra(select={'testparams':'age < %s'}, select_params=[0])\ .aggregate(Sum("age", only=Q(age__gt=29))) self.assertEqual(vals, {"age__sum": 254}) vals = Author.objects.aggregate( Sum("age", only=Q(name__icontains='jaco') | Q(name__icontains='adrian'))) self.assertEqual(vals, {"age__sum": 69})
def test_annotate_basic(self): self.assertQuerysetEqual(Book.objects.annotate().order_by('pk'), [ "The Definitive Guide to Django: Web Development Done Right", "Sams Teach Yourself Django in 24 Hours", "Practical Django Projects", "Python Web Development with Django", "Artificial Intelligence: A Modern Approach", "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp" ], lambda b: b.name) books = Book.objects.annotate(mean_age=Avg("authors__age")) b = books.get(pk=1) self.assertEqual( b.name, 'The Definitive Guide to Django: Web Development Done Right') self.assertEqual(b.mean_age, 34.5)
def get_score(self): # We need to make two aggregate-select to calculate score. Need to find out how to cache it. default_score = { 'score': 0, 'total': self.weight, 'grades': 0, 'own_grades': 0, 'need_grades': self.grades_required, 'passed': False } if self.submission is None: return default_score own_submission = self._get_submission() # Score over user's submission aggregated_score = Score.objects.filter(submission=own_submission) \ .aggregate(avg=Avg('score'), count=Count('submission')) # Check whether user has graded several submissions himself to get his score aggregated_score_own = Score.objects.filter( user_id=self.scope_ids.user_id, submission__module=own_submission.module, submission__course=own_submission.course).aggregate( count=Count('submission')) # Update data default_score['grades'] = aggregated_score['count'] default_score['own_grades'] = aggregated_score_own['count'] # Submission must be graded several times before score can be published if aggregated_score['count'] < self.grades_required: return default_score # User need to grade at least several others' submission before score is published if aggregated_score_own['count'] < self.grades_required: return default_score default_score['score'] = (aggregated_score['avg'] / self.points) * self.weight default_score['passed'] = True return default_score
def test_related_aggregate(self): vals = Author.objects.aggregate(Avg("friends__age")) self.assertEqual(len(vals), 1) self.assertAlmostEqual(vals["friends__age__avg"], 34.07, places=2) vals = Author.objects.aggregate(Avg("friends__age", only=Q(age__lt=29))) self.assertEqual(len(vals), 1) self.assertAlmostEqual(vals["friends__age__avg"], 33.67, places=2) vals2 = Author.objects.filter(age__lt=29).aggregate( Avg("friends__age")) self.assertEqual(vals, vals2) vals = Author.objects.aggregate( Avg("friends__age", only=Q(friends__age__lt=35))) self.assertEqual(len(vals), 1) self.assertAlmostEqual(vals["friends__age__avg"], 28.75, places=2) # The average age of author's friends, whose age is lower than the authors age. vals = Author.objects.aggregate( Avg("friends__age", only=Q(friends__age__lt=F('age')))) self.assertEqual(len(vals), 1) self.assertAlmostEqual(vals["friends__age__avg"], 30.43, places=2) vals = Book.objects.filter(rating__lt=4.5).aggregate( Avg("authors__age")) self.assertEqual(len(vals), 1) self.assertAlmostEqual(vals["authors__age__avg"], 38.2857, places=2) vals = Author.objects.all().filter(name__contains="a").aggregate( Avg("book__rating")) self.assertEqual(len(vals), 1) self.assertEqual(vals["book__rating__avg"], 4.0) vals = Book.objects.aggregate(Sum("publisher__num_awards")) self.assertEqual(len(vals), 1) self.assertEqual(vals["publisher__num_awards__sum"], 30) vals = Publisher.objects.aggregate(Sum("book__price")) self.assertEqual(len(vals), 1) self.assertEqual(vals["book__price__sum"], Decimal("270.27"))
def test_backwards_m2m_annotate(self): authors = Author.objects.filter(name__contains="a").annotate( Avg("book__rating")).order_by("name") self.assertQuerysetEqual(authors, [('Adrian Holovaty', 4.5), ('Brad Dayley', 3.0), ('Jacob Kaplan-Moss', 4.5), ('James Bennett', 4.0), ('Paul Bissex', 4.0), ('Stuart Russell', 4.0)], lambda a: (a.name, a.book__rating__avg)) authors = Author.objects.annotate( num_books=Count("book")).order_by("name") self.assertQuerysetEqual(authors, [('Adrian Holovaty', 1), ('Brad Dayley', 1), ('Jacob Kaplan-Moss', 1), ('James Bennett', 1), ('Jeffrey Forcier', 1), ('Paul Bissex', 1), ('Peter Norvig', 2), ('Stuart Russell', 1), ('Wesley J. Chun', 1)], lambda a: (a.name, a.num_books))
def test_annotate_m2m(self): books = Book.objects.filter(rating__lt=4.5).annotate( Avg("authors__age")).order_by("name") self.assertQuerysetEqual( books, [('Artificial Intelligence: A Modern Approach', 51.5), ('Practical Django Projects', 29.0), ('Python Web Development with Django', Approximate(30.3, places=1)), ('Sams Teach Yourself Django in 24 Hours', 45.0)], lambda b: (b.name, b.authors__age__avg), ) books = Book.objects.annotate( num_authors=Count("authors")).order_by("name") self.assertQuerysetEqual(books, [ ('Artificial Intelligence: A Modern Approach', 2), ('Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', 1), ('Practical Django Projects', 1), ('Python Web Development with Django', 3), ('Sams Teach Yourself Django in 24 Hours', 1), ('The Definitive Guide to Django: Web Development Done Right', 2) ], lambda b: (b.name, b.num_authors))
def test_aggregate_annotation(self): vals = Book.objects.annotate( num_authors=Count("authors__id")).aggregate(Avg("num_authors")) self.assertEqual(vals, {"num_authors__avg": Approximate(1.66, places=1)})
def test_annotate_values(self): books = list( Book.objects.filter(pk=1).annotate( mean_age=Avg("authors__age")).values()) self.assertEqual(books, [{ "contact_id": 1, "id": 1, "isbn": "159059725", "mean_age": 34.5, "name": "The Definitive Guide to Django: Web Development Done Right", "pages": 447, "price": Approximate(Decimal("30")), "pubdate": datetime.date(2007, 12, 6), "publisher_id": 1, "rating": 4.5, }]) books = Book.objects.filter(pk=1).annotate( mean_age=Avg('authors__age')).values('pk', 'isbn', 'mean_age') self.assertEqual(list(books), [{ "pk": 1, "isbn": "159059725", "mean_age": 34.5, }]) books = Book.objects.filter(pk=1).annotate( mean_age=Avg("authors__age")).values("name") self.assertEqual(list(books), [{ "name": "The Definitive Guide to Django: Web Development Done Right" }]) books = Book.objects.filter(pk=1).values().annotate( mean_age=Avg('authors__age')) self.assertEqual(list(books), [{ "contact_id": 1, "id": 1, "isbn": "159059725", "mean_age": 34.5, "name": "The Definitive Guide to Django: Web Development Done Right", "pages": 447, "price": Approximate(Decimal("30")), "pubdate": datetime.date(2007, 12, 6), "publisher_id": 1, "rating": 4.5, }]) books = Book.objects.values("rating").annotate( n_authors=Count("authors__id"), mean_age=Avg("authors__age")).order_by("rating") self.assertEqual(list(books), [{ "rating": 3.0, "n_authors": 1, "mean_age": 45.0, }, { "rating": 4.0, "n_authors": 6, "mean_age": Approximate(37.16, places=1) }, { "rating": 4.5, "n_authors": 2, "mean_age": 34.5, }, { "rating": 5.0, "n_authors": 1, "mean_age": 57.0, }]) authors = Author.objects.annotate(Avg("friends__age")).order_by("name") self.assertEqual(len(authors), 9) self.assertQuerysetEqual( authors, [('Adrian Holovaty', 32.0), ('Brad Dayley', None), ('Jacob Kaplan-Moss', 29.5), ('James Bennett', 34.0), ('Jeffrey Forcier', 27.0), ('Paul Bissex', 31.0), ('Peter Norvig', 46.0), ('Stuart Russell', 57.0), ('Wesley J. Chun', Approximate(33.66, places=1))], lambda a: (a.name, a.friends__age__avg))
def test_aggregate_alias(self): vals = Store.objects.filter(name="Amazon.com").aggregate( amazon_mean=Avg("books__rating")) self.assertEqual(len(vals), 1) self.assertAlmostEqual(vals["amazon_mean"], 4.08, places=2)