简体   繁体   中英

Calculate percentage based on the sum value in the django view

I would like to display the percentage mark instead of the total sum of the mark. Right now i have a table that display the student name and their mark attendance. I would like to convert the mark attendance into a percentage. the current implementation is:

Student Name Attendance

Annie 200

Anny 150

But i would like to show the attendance in percentange. for example: Student Name Attendance

Annie 100%

Anny 85%

i am not sure how to implement the method. But i have tried this:

# models.py: 

class MarkAtt(models.Model):
    studName = models.ForeignKey(
        Namelist, on_delete=models.SET_NULL, blank=True, null=True, default=None,
    )
    classGrp = models.ForeignKey(GroupInfo, on_delete=models.SET_NULL, null=True)
    currentDate = models.DateField(default=now())
    week = models.IntegerField(default=1)
    attendance = models.IntegerField(default=100) #1 is present

    def get_percentage(self):
        ttlCount = MarkAtt.objects.filter(studName).count()
        perc = ttlCount / 1100 *100
        return perc



# views.py:

def attStudName(request):

    students = MarkAtt.objects.values('studName__VMSAcc').annotate(mark=Sum('attendance'))
    context = {'students' : students}
    return render(request,'show-name.html', context)

So you have your numerator but you need your denomenator. I'm not exactly sure what your denomenator should be with your current setup but creating a new field that uses "Count" rather than "Sum" might do the trick for you. Then you would divid the sum field by the count field. I would probably just do this in the view and not mess with the model.

You can use the formatting mini-language to express a percentage in a string

>>> attendence = 20
>>> total = 100
>>> '{:%}'.format(attendence/total)
'20%'

Bear in mind this will return the answer as string instead of an int or float

To use this in your get_percentage , there are a few issues that will need to be addressed:

  • studName is not defined or passed into the method but is used in the filter query. This will cause a NameError .
  • Your filter query looks like it is just counting the students in the filter query instead of summing the attendance. You should use a sum annotation like you have done in the view.
  • You will need to be able to get the value for 100% attendance to be able to divide by it.

To modify your implimentatiom of this on the model you could do something like this.

    def get_percentage(self):
        student = MarkAtt.objects.filter(studName=self.studName).annotate(mark=Sum('attendance'))
        return '{:%}'.format(student.mark / 1100)

However, I don't think the MarkAtt model is the right place to do this as many MarkAtt objects could relate to one NameList object resulting in possibly running the same query several times for each student. I think it would be better to do this on NameList or the view itself.

class NameList(models.Model):

    ...

    def get_percentage(self):
        attendance = self.markatt_set().annotate(total=Sum('attendance'))
        return '{:%}'.format(attendance.total / 1100)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM