On submit a Django ChoiceField form only returns the first dictionary in the formset

Viewed 78

I have defined a formset that has 2 forms in the following order.

  1. Type Number (Student ID)
  2. 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:

  1. Type Number (Student ID)
  2. 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)
0 Answers
Related