Skip to content

Instantly share code, notes, and snippets.

@IlianIliev
Created October 2, 2018 09:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IlianIliev/8c2f69dcdf590c0a476afc130f6fc972 to your computer and use it in GitHub Desktop.
Save IlianIliev/8c2f69dcdf590c0a476afc130f6fc972 to your computer and use it in GitHub Desktop.
from django.db import models
from django.db.models import Avg
class Blog(models.Model):
name = models.CharField(max_length=100)
rating = models.DecimalField(max_digits=5, decimal_places=2, null=True)
def __str__(self):
return self.name
def calc_average(self):
return self.entry_set.aggregate(res=Avg('rating'))['res']
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
rating = models.IntegerField(default=5)
def __str__(self):
return self.headline
from django.db.models import Avg, OuterRef, Subquery
from django.test import TestCase
from .models import Blog, Entry
class BlogTestCase(TestCase):
def setUp(self):
# preparing some fake data
for blog_num in range(0, 3):
blog = Blog.objects.create(name='{}'.format(blog_num))
for entry_num in range(0, 4):
headline = 'Entry {} for blog {}'.format(entry_num, blog_num)
Entry.objects.create(blog=blog, headline=headline, rating=blog_num * 10)
def test_calc_average(self):
blog = Blog.objects.get(name='1')
self.assertEqual(blog.calc_average(), 10)
blog = Blog.objects.get(name='2')
self.assertEqual(blog.calc_average(), 20)
def test_avg(self):
Blog.objects.update(
rating=Subquery(
Blog.objects.filter(
id=OuterRef('id')
).annotate(
avg_rating=Avg('entry__rating')
).values('avg_rating')
)
)
blog = Blog.objects.get(name='1')
self.assertEqual(blog.calc_average(), 10)
blog = Blog.objects.get(name='2')
self.assertEqual(blog.calc_average(), 20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment