Search code examples
pythondjangojinja2

Data fetching issues from table which is using jinja2 (django)


I have a table which contains some list of student from my database, I want to fetch data from that html table which contains data from database but I want to add if the student is present or not.

I have a code which works perfectly but there is an issue that my functions only takes last row data and skips all other rows.

HTML code

<div class="container">
  <form method="POST" action="takeattendance">
    {% csrf_token %}
    <div class="form-group">
      <h4 style="color:white;"> Select Subject For Attendance</h4>
      <select class="btn btn-success" name="subject">
          <option selected disabled="true">Subject</option>
          {% for sub in subjects%}
          <option value="{{ sub.id }}">{{sub.subject_name}}</option>
          {%endfor%}
      </select>
  </div>
    <table class="table">
        <thead>
          <tr>
            <th scope="col" style="color:white;"><b>Email</b></th>
            <th scope="col" style="color:white;"><b>Roll No.</b></th>
            <th scope="col" style="color:white;"><b>First Name</b></th>
            <th scope="col" style="color:white;"><b>Last Name</b></th>
            <th scope="col" style="color:white;"><b>Year</b></th>
            <th scope="col" style="color:white;"><b>Division</b></th>
            <th scope="col" style="color:white;"><b>Batch</b></th>
            <th scope="col" style="color:white;"><b>Attendance</b></th>
          </tr>
        </thead>
        <tbody>
            {% for student in students %}
            {% if user.staff.class_coordinator_of  == student.division and user.staff.teacher_of_year == student.year %}
          <tr>
            <td style="color:white;"><input type="hidden" name="student_name" value="{{student.id}}" >{{student.user}}</td>
            <td style="color:white;">{{student.roll_no}}</td>
            <td style="color:white;">{{student.user.first_name}}</td>
            <td style="color:white;">{{student.user.last_name}}</td>
            <td style="color:white;">{{student.year}}</td>
            <td style="color:white;">{{student.division}}</td>
            <td style="color:white;">{{student.batch}}</td>
            <td>
              <div class="form-group">
                <select class="btn btn-success" name="status" id="status">
                    <option selected value="Present">Present</option>
                    <option value="Absent">Absent</option>
                </select>
                </div>                 
            </td>
          </tr>
          {%  endif %}          
          {% endfor %}
        </tbody> 
      </table>
      <div class="form-group">
        <button type="submit" class="btn btn-info btn-lg ">Add</button>
    </div>
    </form>
 </div> 

views.py

def takeattendance(request):
    if request.method == "POST":
        subject = Subject.objects.get(id=request.POST['subject'])
        student = Student.objects.get(id=request.POST['student_name'])
        status = request.POST['status']
        print(subject)
        print(student)
        print(status)
        attendance = Attendance(subject=subject, student=student, status=status)
        attendance.save()

        if request.user.is_authenticated and request.user.user_type == 2:
            return render(request,'ms/hod/Attendance.html')

        if request.user.is_authenticated and request.user.user_type == 3:
           return render(request,'ms/staff/Attendance.html')
        else:
            return HttpResponse("Failed")

    else:    
        return HttpResponse("Failed")

The above code works perfectly but only gets the last row data, whereas I want all the rows and the attendance of every student of every row


Solution

  • Use .getlist() if you want to get multiple data from a single key

    Example 1

    def takeattendance(request):
        if request.method == "POST":
            subject = Subject.objects.get(id=request.POST['subject'])
            student_ids = request.POST.getlist('student_name')
            status = request.POST['status']
    
            for sid in student_ids:
                Attendance.objects.create(
                    subject=subject,
                    student=Student.objects.get(id=sid),
                    status=status
                )
    
            if request.user.is_authenticated and request.user.user_type == 2:
                return render(request,'ms/hod/Attendance.html')
    
            if request.user.is_authenticated and request.user.user_type == 3:
               return render(request,'ms/staff/Attendance.html')
            else:
                return HttpResponse("Failed")
    
        else:    
            return HttpResponse("Failed")
    

    above code will work fine but it will hit database on each iteration to solve that you can use .bulk_create()

    Example 2

    def takeattendance(request):
        if request.method == "POST":
            subject = Subject.objects.get(id=request.POST['subject'])
            student_ids = request.POST.getlist('student_name')
            status = request.POST['status']
    
            attendance_objs = []
            for sid in student_ids:
                attendance_objs.append(
                    Attendance(
                      subject=subject,
                      student=Student.objects.get(id=sid),
                      status=status
                    )
                )
            
            Attendance.objects.bulk_create(
                    attendance_objs
            )
    
            if request.user.is_authenticated and request.user.user_type == 2:
                return render(request,'ms/hod/Attendance.html')
    
            if request.user.is_authenticated and request.user.user_type == 3:
               return render(request,'ms/staff/Attendance.html')
            else:
                return HttpResponse("Failed")
    
        else:    
            return HttpResponse("Failed")
    

    Note

    Before using bulk_create() I will suggest you to read some caveats of .bulk_create()