4

I have two models which look like the following:

class Subject(models.Model):

   subject_code = models.CharField(max_length=12, unique=True)
   name = models.CharField(max_length=100)
   dept_code = models.CharField(max_length=6)

and...

class Subject_assessment(models.Model):    
   subject_code = models.ForeignKey(Subject, related_name='sub_assessments')
   year = models.CharField(max_length=4)
   name = models.CharField(max_length=50)

I have created my serializes in such a way that when I retrieve a subject, I also retrieve the assessments associated with that subject. I am using the following serializers to accomplish this:

class AssessmentsSerializer(serializers.ModelSerializer):
class Meta:
    model = Subject_assessment
    fields = (
        "subject_code", "year", "name"
    )

class SubjectSerializer(serializers.ModelSerializer):
sub_assessments = AssessmentsSerializer(many=True)
class Meta:
    model = Subject
    fields = (
        "subject_code", "name", "dept_code",            
        "sub_assessments"
    )

This code works perfectly as anticipated as it gives me a result like this:

{
 "subject_code":"ECR2243",
 "name":"Statistics",
 "dept_code":"Stats",
 "sub_assessments":[
     {
       "subject_code":"ECR2243",
       "year":"2017",
       "name":"Test 1"
     },
     {
       "subject_code":"ECR2243",
       "year":"2016",
       "name":"Test 1"
     }
 ]
}

My problem is that I wish to retrieve assessments only for a specific year. For example, If I pass 2017 as the year of interest, I do not wish to retrieve assessments for 2016 like I am currently getting.

Can anyone please assist on how I can structure my code in order to accomplish this. Thank you in advance.


Edit 1 My views.py is as follows:

class  SubjectViewSet(viewsets.ModelViewSet):
serializer_class = SubjectSerializer
lookup_field = 'subject_code'

def get_queryset(self):
    qry_subject_code = self.request.GET.get('subject_code')
    retrieved_sub = Subject.objects.filter(subject_code=qry_subject_code)
    return retrieved_sub
3
  • Can you expand your question with view.py Commented Feb 10, 2017 at 10:44
  • Check django-rest-framework.org/api-guide/serializers/…. It has details on how to pass extra parameters to your serializer. It can help you construct a solution. Commented Feb 10, 2017 at 10:46
  • @marin I have added my views.py Commented Feb 10, 2017 at 10:51

2 Answers 2

6

This is the solution that worked for me to this question:

class FilteredAssessmentsSerializer(serializers.ListSerializer):
    def to_representation(self,data):
       qry_year = self.context['request'].GET.get('year')
       data = data.filter(year=qry_year)
       return super(FilteredAssessmentsSerializer,  self).to_representation(data)

class AssessmentsSerializer(serializers.ModelSerializer):
   class Meta:
      model = Subject_assessment
      list_serializer_class = FilteredAssessmentsSerializer
      fields = '__all__'

class SubjectSerializer(serializers.ModelSerializer):
   sub_assessments = AssessmentsSerializer(many=True)
   class Meta:
       model = Subject
       fields = (
          "subject_code", "name", "dept_code",
          "faculty_code", "university_code", "description",
          "sub_assessments"
       )

Reference: I combined the following solutions to come up with one that suits me.

How can I apply a filter to a nested resource in Django REST framework?

https://stackoverflow.com/a/28354281/7210105

Sign up to request clarification or add additional context in comments.

Comments

0

Can you try with this query:

retrieved_sub = Subject_assessment.objects.filter(subject_code__in=Subject.objects.filter(subject_code=qry_subject_code),year='2014').all()

6 Comments

Not working. What would be the reason of putting .all() there?
Can you do some print #retrieved_sub# when you call that URL? Because .all() will return all values from query.
Not sure if you getting my question correctly. My code is returning results from the DB, check the question. My question is how to filter the results from the nested serializer by year
Your suggestion works to retrieve the desired output. However I will not mark it as the answer because it changes the form I require my output in. I still need the details of the subject in question without need to run another query.
If you find other way beside this, please update your question with answer. @Tatenda
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.