I have defined a formset that has 2 forms in the following order.
- Type Number (Student ID)
- Type Text (Course Name)
View.py
for form in formset:
if form.has_changed():
print(form.cleaned_data)
When a post request is submitted the formset.cleaned_data returns
[{'student_id': 1, 'course_name': 'English'}, {'student_id': 2, 'course_name': 'Math'}, {'student_id': 3, 'course_name': 'PE'}]
I have also added a check if a form.has_changed(), so if I submit 'History' instead of 'English' where id is equal to 1 my form.cleaned_data returns the expected dictionary.
{'student_id': 1, 'course_name': 'History'}
My issue:
When I had a type text form for 'course_name' everything was working as intended. I only faced an issue when I changed the text form to be single-select instead, so the formset is as follows:
- Type Number (Student ID)
- Type ChoiceField (Course Name)
The formset.cleaned_data returns the same list of dictionaries.
[{'student_id': 1, 'course_name': 'English'}, {'student_id': 2, 'course_name': 'Math'}, {'student_id': 3, 'course_name': 'PE'}]
However, if I submit 'History' to change the 'PE' course where id is equal to 3 the form.cleaned_data always returns the first dictionary in the list.
{'student_id': 1, 'course_name': 'English'}
Why is this happening? Is there any issue with using ChoiceField in the formset?
When I made the change to single-select it seems like the form variable is not looping through the formset properly since it only returns the first dictionary in the list.
[EDIT]
VIEW.PY
def generate_student_info(request):
# Retrieve inputted value
current_student_id = request.POST.get('student_id')
current_course_name = request.POST.get('course_name')
# Read the table from the database
connection = db.open_connection(read_only=False)
sql_str = f"""SELECT * FROM {students_table};"""
df = db.read(sql_statement=sql_str, connection=connection)
# creating a formset
insert_formset = formset_factory(StudentInfoForm, extra=0)
formset = insert_formset(request.POST or None, initial=[{'student_id': df['student_id'][i], 'course_name': df['course_name'][i]} for i in range(len(df))])
if request.method == 'POST':
if formset.is_valid():
for form in formset:
if form.has_changed():
print(form.cleaned_data)
try:
#some MySQL code to be executed
else:
print('formset is not valid')
context = {'formset': formset}
return render(request, 'student_info_table.html', context)
FORMS.PY
class StudentInfoForm(forms.Form):
student_id = forms.IntegerField(label='student_id', required=False, min_value=0)
# course_name= forms.ChoiceField(
# choices=[(student_info_df['course_name'][i], student_info_df['course_name'][i]) for i in
# range(len(student_info_df))],
# label="")
course_name= forms.CharField(label='course_name', required=False)