user3525985
user3525985

Reputation: 109

How can I calculate average scores from these entries in django?

So I have this model:

class scoreShow(models.Model):
    dancer = models.ForeignKey(dancer)
    s1 = models.IntegerField(max_length = 2)
    s2 = models.IntegerField(max_length = 2)
    s3 = models.IntegerField(max_length = 2)
    s4 = models.IntegerField(max_length = 2)
    s5 = models.IntegerField(max_length = 2)
    s6 = models.IntegerField(max_length = 2)
    s7 = models.IntegerField(max_length = 2)
    counter = models.IntegerField(max_length = 2)
    stotal = models.IntegerField(max_length = 3)
    field_1 = models.IntegerField(max_length = 20, null=True, blank=True)
    field_2 = models.CharField(max_length = 20, null=True, blank=True)

    def __unicode__(self):
        return str(self.dancer) 

Which is fed information from this view form:

def scores(request):
     perf = dancer.objects.filter(perform=True)

     if request.method =='POST':
        intpk = request.POST.get("form")
        whendone = request.POST.get("done")

        contestant =dancer.objects.get(pk=intpk)

        showcase = inlineformset_factory(dancer, scoreShow, extra = 1)
        form = showcase(instance=None)

        if whendone == "save":

            form = showcase(request.POST, request.FILES, instance=contestant)
            if form.is_valid():
                form.save()

     return render_to_response("scores.html",locals(), context_instance = RequestContext(request))

It accepts numeric values from 1 to 10 from about 13 people. I need to calculate the average of the scores that the 13 people put in. 2 averages:

  1. The average of the 7 categories ex. average of s1, average of s2 &

  2. The average of all of the S's added together so average of s1 total+ s2 total ... divided by total entries. T

I would also like to avoid having anyone submit a score twice if thats possible. Can anyone help me with this?

Upvotes: 2

Views: 558

Answers (1)

daniula
daniula

Reputation: 7028

  1. You can use Aggregation feature by calling:

    from django.db.models import Avg
    qs = ScoreShow.objects.all()
    return qs.aggregate(Avg('s1'), Avg('s2'), Avg('s3'), Avg('s4'), Avg('s5'), Avg('s6'),Avg('s7'))
    

    or a little shorter:

    qs = ScoreShow.objects.all()
    return qs.aggregate(*[Avg('s%d' % i) for i in range(1, 8)])
    
  2. To calculate average value of all scores together you need to combine aggregate with annotate:

    from django.db.models import Avg, Sum
    fields = ['s%d' % i for i in range(1,8)]
    qs = ScoreShow.objects.annotate(sAll=Sum('id', field='+'.join(fields))).all()
    return qs.aggregate(Avg('sAll'))
    
  3. To make sure that nobody submits two scores add unique=True to dancer foreign key:

    class ScoreShow(models.Model):
        dancer = models.ForeignKey(dancer, unique=True)
    

Upvotes: 1

Related Questions