djangodjango-formsformsetdjango-formtools

django - How can I prefill formset forms data using database query result?


I am creating a student attendance form where need to get details of student name, student class and Id from student model based on teacher selecting student class in one form. I have tried using initial by using for loop on query data to prefill the form in formset, however it populates data for one record only. Below is the code for forms.py, models and views.py. Can someone help on this

forms.py

class student(models.Model):
    studentid = models.AutoField(primary_key=True)
    Gender = models.CharField(max_length=6, choices=gender, null=True)
    Name = models.CharField(max_length=100, null=True)
    DOB = models.DateField(null=True)
    Image = models.ImageField(null=True, upload_to='images')
    Status = models.CharField(max_length=10, choices=statchoice, null=True)
    Father_name = models.CharField(max_length=100, null=True)
    Mother_name = models.CharField(max_length=100, null=True)
    Address = models.CharField(max_length=200, null=True)
    Contact_no = models.IntegerField(null=True)
    Email = models.EmailField(null=True)
    Admission_class = models.CharField(max_length=40, null=True, choices=grade)
    Admission_date = models.DateField(null=True)
    Current_class = models.CharField(max_length=40, null=True, choices=grade)
    Leaving_date = models.DateField(null=True, blank=True)
    objects = models.Manager() 
    def __str__(self):
        return str(self.studentid)  

class student_attendance(models.Model):
    Student_ID = models.CharField(max_length=100, null=True)
    Student_Name = models.CharField(max_length=100, null=True)
    Student_class = models.CharField(max_length=100, null=True, choices=grade)
    Attendance_date = models.DateField(null=True, auto_now_add=True, blank=True)
    Attendance_status = models.CharField(choices=attendance, null=True, max_length=10)
    objects = models.Manager() 

Views.py

def student_attend(request):
if request.method == 'POST':
    data = request.POST.get('studentGrade')
    formset_data = student.objects.filter(Current_class=data)
    AttendanceFormSet = formset_factory(std_attendance, extra=(len(formset_data))-1)
    for element in formset_data:
        formset = AttendanceFormSet(initial=[
            {'Student_ID': element.studentid, 'Student_Name':element.Name, 'Student_class':element.Current_class, 'Attendance_status':"Present"}
        ])
    param = {'formset':formset} 
    return render(request, 'home/student_attendance.html', param)     
return render(request, 'home/student_attendance.html')

form.py:

class student_register(ModelForm):
class Meta:
    model = student
    fields = '__all__'

class std_attendance(ModelForm):
class Meta:
    model = student_attendance
    fields = '__all__'

Solution

  • Each iteration in your loop you override the formset, that is why only a single form is filled, you need to fill the param with all the forms inside the loop this way:

    initial = []
    for element in formset_data:
            initial.append({'Student_ID': element.studentid, 'Student_Name':element.Name, 'Student_class':element.Current_class, 'Attendance_status':"Present"}
            
    formset = AttendanceFormSet(initial=initial)