Нахождение наибольшей суммы экземпляра в моделях django

У меня есть две модели, которые имеют отношения внешнего ключа друг к другу.

Одна из моделей - это Student, а другая - Grade.

Проблема, с которой я сталкиваюсь, заключается в том, что я получаю нужные мне значения с помощью методов модели в шаблоне. Так что я пытаюсь сделать то, что мне нужен студент с наивысшим баллом оценки, вплоть до самого низкого.

Как я могу этого достичь?

class Student(models.Model):
    user = models.OneToOneField(User,on_delete=models.SET_NULL,null=True,related_name="student")
    student_name = models.CharField(max_length=15)
    
    def get_grades(self):
        today = datetime.date.today()
        return self.student_grade.filter(Date_created__year=today.year,Date_created__month=today.month)
    def get_passed(self):
        today = datetime.date.today()
        return self.student_grade.filter(Date_created__year=today.year,Date_created__month=today.month, State="Passed")

States = (("Pending","Pending"),("Passed","Passed"),("Failed","Failed"))
class Grade(models.Model):
    student = models.ForeignKey(Student,on_delete=models.SET_NULL,blank=True, null=True,related_name="student_grade")
    State = models.CharField(choices=States,default="Pending",max_length=26)
 

    def __str__(self):
        return self.student

Вам нужно будет использовать аннотацию Django для подсчета количества оценок "Прошел", это должно сработать для вас:

from django.db.models import Count, Case, When, IntegerField

students = Student.objects.annotate(pass_marks=Count(
    Case(When(student_grade__state="Passed", then=1),
        output_field=IntegerField(),
    ))
)

Затем у вас есть набор запросов, с которым вы можете работать в представлении, и шаблон, который содержит всю информацию о студентах, но также имеет свойство .pass_marks, которое дает вам количество сданных оценок.

Если вы хотите сжать это в несколько значений или упорядочить, вы можете использовать другие функции Django, такие как .values('student_name','pass_marks') и .order_by('-pass_marks')

Вернуться на верх