简体   繁体   中英

Django: Queryset filtering based on min max set in another table

Consider the following models:

Class ExamResults:
   ...
   Marks = models.IntegerField(default=0, null=True, blank=True)
   Course = models.CharField(max_length=255, null=True)
   Academic_year = models.CharField(max_length=255, null=True)

Class ExamSetting:
   ...
   GradeAThreshold = models.IntegerField(default=0, null=True, blank=True)
   GradeBThreshold = models.IntegerField(default=0, null=True, blank=True)
   ...
   Course = models.CharField(max_length=255, null=True)
   Academic_year = models.CharField(max_length=255, null=True)

Now I have an API to search/get results from ExamResults for all students. The API works fine and I use Q filters to filters the results. For eg

...
year_contains = self.request.GET.get("year_contains", "")
if year_contains:
      q_filt |= Q(Academic_year__icontains=year_contains)
      
queryset = queryset.filter(q_filt)

...

Now I have a requirement to filter the queryset for the following condition:

  1. List of exam results where the Marks exceed GradeAthreshold
  2. List of exam results where the Marks are less than GradeAthreshold and exceed GradeBThreshold and so on

What would be the best way of doing this? The ExamResults table and ExamSetting has two common fields which can narrow down the thresholds. For eg I use the below code in serializer to check if the result has Grade A or not:

setting = ExamSetting.objects.filter(Academic_year=obj.Academic_year, Course=obj.Course, is_active=True).first()
if obj.Marks >= setting.GradeAThreshold:
   # Grade A
...

This does work and I do get the results with grades. Now how do I add something like this in the queryset so that I can filter the results for Grade A or B results?.

As you mentioned ExamSetting and ExamResult both have common fields; assuming proper data integrity, you can pivot based on one of those.

For example, if you want all exam results with grade A or above for a similar course:

setting = ExamSetting.objects.filter(
    Academic_year=obj.Academic_year, 
    Course=obj.Course, 
    is_active=True
    ).first()

query = Q(Course=setting.Course) & Q(Mark__gte=setting.GradeAThreshold)
ExamResults.objects.filter(query)

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