'Queryset takes too long to populate data

I have a django view that generates a form depending on POST or GET. It works well with little data on the Student model but stagnates when the data gets big. Is there a remedy I can apply?? Here's the view

def My_View(request,pk):
    if request.method == 'POST':
        try:
            form = NewIssueForm(request.POST,school= request.user.school,pk=pk,issuer = request.user)
            if form.is_valid():
                name = form.cleaned_data['borrower_id'].id
                form.save(commit=True)
                books = Books.objects.get(id=pk)
          
                Books.Claimbook(books)
                return redirect('view_books')
                messages.success(request,f'Issued successfully')
        except Exception as e:
            messages.warning(request,f"{e}")
            return redirect('view_books')    
    else:
        form = NewIssueForm(school= request.user.school,pk=pk,issuer = request.user)
    return render(request, 'new_issue.html', {'form': form})

Here's the form

class NewIssueForm(forms.ModelForm):
    def __init__(self,*args, pk,school,issuer, **kwargs):
        super(NewIssueForm, self).__init__(*args, **kwargs)
        booqs = Books.objects.filter(school=school).get(id=pk)
        self.fields['issuer'].initial = issuer
        self.fields['borrower_id'].Student.objects.filter(school = school)
        self.fields['book_id'].label = str(booqs.book_name) + " - " + str(booqs.reg_no)
        self.fields['book_id'].initial = pk
  
    class Meta:
        model = Issue
        fields = ['issuer','book_id','borrower_id','due_days']
        widgets = {
            'book_id':forms.TextInput(attrs={"class":'form-control','type':''}),
            'issuer':forms.TextInput(attrs={"class":'form-control','type':'hidden'}),
            'borrower_id': Select2Widget(attrs={'data-placeholder': 'Select Student','style':'width:100%','class':'form-control'}),
            'due_days':forms.TextInput(attrs={"class":"form-control"}),

Student model

class Student(models.Model):                                    
    school = models.ForeignKey(School, on_delete=models.CASCADE)
    name = models.CharField(max_length=200,help_text="The student's name in full")
    now = datetime.datetime.now()
    YEAR = [(str(a), str(a)) for a in range(now.year-5, now.year+1)]
    year = models.CharField(max_length=4, choices = YEAR,help_text='The year the student is admitted in school')
    student_id = models.CharField(max_length=40,help_text = "This is the student's admission number")
    klass = models.ForeignKey(Klass,on_delete=models.CASCADE)
    stream = models.ForeignKey(Stream,on_delete=models.CASCADE)
    graduated = models.BooleanField(default=False,help_text = "Tick the box to mark the student as graduated")
    prefect = models.BooleanField(default=False,help_text = "Tick the box to select the student as a prefect")

    def __str__(self):
        return "%s - %s - F%s %s"%(self.student_id,self.name,self.klass,self.stream)
    class Meta:
        verbose_name_plural = 'Students'
        unique_together = ("school", "student_id",)
        indexes = [models.Index(fields=['student_id']),
                   models.Index(fields=['name', ]),


Solution 1:[1]

The reason this happens is because when you render the Student, it will need to fetch the related Klass and Stream objects, and will make a query per Student object. This problem is called an N+1 problem since fetching n student requires one query to fetch all the Students, and then one query per Student for the Klasses, and one query per Student for the Streams.

You can select the data when you select the students with:

self.fields['borrower_id'].Student.objects.filter(
    school=school
).select_related('klass', 'stream')

Depending on the __str__ implementations of other models, you might have to select data along with these models as well.

Solution 2:[2]

Can't guess your model but it seems like select_related may play a trick.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Willem Van Onsem
Solution 2 satta sunder talukder