H
H
HolmesInc2016-07-10 16:31:42
Django
HolmesInc, 2016-07-10 16:31:42

How to call a method in the serializer once that will receive data for the remaining fields?

In words, it looks like this: I get all the information about students from the Students model, pass it to the serializer and then, based on the student id, I need to find out if he has debts contained in the Debtors model in the debt field (approximately as it looks in code I described below).

# model.py
class Students(models.Model):
   first_name = models.CharField(...)
   last_name = models.CharField(...)
   budget = models.BooleanField(...)

class Debtors(models.Model):
   debt = models.CharField(...)
   student_id = models.ForeignKey(...)

# viewset.py
class StudentsSet(viewsets.ModelViewSet):
   queryset = Students.objects.all()
   serializer_class = StudentsSerializer

   def get_queryset(self):
      queryset =  Students.objects.filter(budget=True)
      return queryset

# serializer.py
class StudentsSerializer(serializers.ModelSerializer):
   info = serializers.SerializerMethodField('get_info')
   class Meta:
      model = Students
      fields = ('id', 'info')

   def get_info(self, instance):
      return debt_info = Debtors.objects.filter(student_id=instance.id)

The bottom line is that for each individual student id there will be a separate request to the Debtors model, and this is not productive. I'm trying to find a way to call a method once that will get data from Debtors for all available ids at once, and then distribute this information for each student. If writing a query in SQL, then I want to convert this:
Select debt
From Debtors
Where student_id = какой-то id

In it:
Select debt
From Debtors
Where student_id In (какой-то id, какой-то id, какой-то id)

I will be very grateful for the options ^^

Answer the question

In order to leave comments, you need to log in

2 answer(s)
H
HolmesInc, 2016-07-12
@HolmesInc

The problem is solved by using the constructor in the serializer:

def __init__(self, *args, **kwargs):
# getting and prepare data
# ...
super(StudentsSerializer, self).__init__(*args, **kwargs)

Maybe someone will be useful

R
Roman Kitaev, 2016-07-10
@deliro

student_id = models.ForeignKey(...)

Mistake. You are assigning an object, not an ID
queryset =  Students.objects.filter(budget=True)
return queryset

extra line
info = serializers.SerializerMethodField('get_info')
class Meta:

Not according to PEP
Mistake.
Error + you can use feedback
Debtors.objects.filter(student__in=your_students_list)
Premature optimization?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question