I am trying to save attendance in my Django attendance app but keep getting TypeError, expected string or bytes-like object

Viewed 102

So I am trying to create attendance for my student_attendance model but keep getting the TypeError. I have tried everything, checked several solutions on this platform, none have worked.

The error looks like this:

TypeError at /attendance/student/
expected string or bytes-like object
Request Method: POST
Request URL:    http://127.0.0.1:8000/attendance/student/?reg_class=1
Django Version: 3.1
Exception Type: TypeError
Exception Value:    
expected string or bytes-like object
Exception Location: line 75, in parse_date
Python Executable:  C:\Users\Mrs Onajide\Desktop\school_management_system\.venv\Scripts\python.exe
Python Version: 3.8.3

My View

from django.shortcuts import render, redirect
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .forms import SearchEnrolledStudentForm, AttendanceForm, DateForm
from student.models import EnrolledStudent
from academic.models import ClassRegistration
from .models import StudentAttendance
from django.forms.formsets import formset_factory

def student_attendance(request):
    forms = SearchEnrolledStudentForm()
    class_name = request.GET.get('reg_class', None)
    if request.method == 'POST':
        class_info = ClassRegistration.objects.get(id=class_name)
        student = EnrolledStudent.objects.filter(class_name=class_name)
        count = student.count()
        attendance_formset = formset_factory(AttendanceForm, extra=count)
        formset = attendance_formset(request.POST)
        date = DateForm(request.POST)
        list = zip(student,formset)
        if formset.is_valid():
            for form, student in zip(formset,student):
                mark = form.cleaned_data['mark_attendance']
                StudentAttendance.objects.create_attendance(class_info.name, student.roll, mark, date)
                return redirect('home')

My Model

from django.db import models
from academic.models import ClassRegistration
from student.models import EnrolledStudent
from django.utils import timezone

class AttendanceManager(models.Manager):
    def create_attendance(self, std_class, std_roll, std_id, datel):
        std_cls = ClassRegistration.objects.get(name=std_class)
        std = EnrolledStudent.objects.get(roll=std_roll, class_name=std_cls)
        std_att = StudentAttendance.objects.create(
            class_name=std_cls,
            student = std,
            status = std_id,
            date = datel
        )
        return 
    def class_attendance(self, std_class, date):
        ctd = ClassRegistration.objects.get(name=std_class)
        std_att = StudentAttendance.objects.filter(class_name= ctd, date=date)   
        return std_att 

class_attendance = (
    ('Present','Present'),
    ('Absent','Absent'),
)

class StudentAttendance(models.Model):
    class_name = models.ForeignKey(ClassRegistration, on_delete=models.CASCADE)
    student = models.ForeignKey(EnrolledStudent, on_delete=models.CASCADE)
    status = models.CharField(choices=class_attendance, max_length=9)
    date = models.DateField(default=timezone.now, blank=True, null=True)

    objects = AttendanceManager()

    class Meta:
        unique_together = ['student', 'date']

    def __str__(self):
        return str(self.student.student.personal_info.name)

My Form

from django import forms
from academic.models import ClassRegistration

class SearchEnrolledStudentForm(forms.Form):
    reg_class = forms.ModelChoiceField(queryset=ClassRegistration.objects.all())

class_attendance = (
    ('Present','Present'),
    ('Absent','Absent'),
)

class AttendanceForm(forms.Form):
    mark_attendance = forms.ChoiceField(widget=forms.RadioSelect, choices=class_attendance)

class DateForm(forms.Form):
    date = forms.DateField()
1 Answers

You're passing a form instance instead of a date to create_attendance.

See this line in your code:

date = DateForm(request.POST)

Your date variable contains a form with data bound from the POST. You need to do the same thing you're doing with the formset you create with AttendanceForm and check if the form is valid, then pull the value of date out of cleaned_data:

dateform = DateForm(request.POST)
if dateform.is_valid():
    date = dateform.cleaned_data['date']

This will give you the correct value to then submit to your call to create_attendance:

StudentAttendance.objects.create_attendance(class_info.name, student.roll, mark, date)
Related