Using a Select filter to narrow choices for a form.

Please post the actual code you are trying here.

Side note: That path should be 'student/<str:school_id>/', because the primary key of the School model is a string.

Sure thing.

The url:

path('student/<str:school_id>', views.course_selection, name='courses'),

The views:

def choose_school7(request):
	
	
		aschool = Courses.objects.all()
		form=SelectSchoolForm(request.POST)
		if request.method == "POST":
			if form.is_valid():
				school = form.cleaned_data['school']
				messages.success(request, "School chosen successfully!")

				return redirect('courses', school_id=school.id)
		context = {'form': form, 'aschool':aschool}  
		return render(request, 'choose_school7.html', context)	

def course_selection(request, school_id):

		form = SelectCourseForm(school_id, request.POST or None)
		if form.is_valid():
			form.save()
			messages.success(request, "Record added successfully!")
			return redirect('school')
		context = {'form':form}
		return render(request, 'course_selection.html', context)

and the forms:

class SelectSchoolForm(forms.ModelForm):

        class Meta:
                model = Courses
                fields = ('school', )
                labels = {'school':'School', }
                widgets = {'school': forms.Select(attrs={"placeholder":"School", "class":"form-select"}),

                 }

class SelectCourseForm(forms.ModelForm):

			def __init__(self, school, *args, **kwargs):
				super().__init__(self, *args, **kwargs)
				self.fields['course'].queryset = Courses.objects.filter(school_id=school)
                            
			class Meta:
				model = Student
				fields = ( 'student_id', 'course')
				labels = {'student_id':'', 'course':''}
				widgets = {'student_id':forms.widgets.TextInput(attrs={"placeholder":"Student ID", "class":"form-control"}),
               			'course':forms.widgets.Select(attrs={"placeholder":"Course", "class":"form-select"}),
              
               
                }

If there’s anything else you need, I’ll be happy to include it. Thanks.

Are you importing that form in your views.py file?

Oh. No. Sorry. I fixed that. Now I get:

"AttributeError at /student/UoW

‘SelectCourseForm’ object has no attribute ‘get’"

Also, I just noticed:

You’re not checking for a POST vs GET request in this view. You’re checking form.is_valid() in both circumstances.

You’re also not getting the Student instance to be edited by the form. (See the skeleton that I posted above at Using a Select filter to narrow choices for a form. - #15 by KenWhitesell)

Oops! I missed that! Thank you for pointing out @KenWhitesell

So I’ve added in the if request.method == “POST”: but I still have the error: "AttributeError at /student/UoW

‘SelectCourseForm’ object has no attribute ‘get’"

For completeness, that view is now:

def course_selection(request, school_id):

		form = SelectCourseForm(school_id, request.POST or None)
		if request.method == "POST":
			if form.is_valid():
				form.save()
				messages.success(request, "Record added successfully!")
				return redirect('school')
		context = {'form':form}
		return render(request, 'course_selection.html', context)

Ken: I’m not sure what you mean by “You’re also not getting the Student instance to be edited by the form. (See the skeleton that I posted above”. I don’t understand why I need the student id to be passed at all, we’re creating a new instance of student, not updating a student.

Your view needs both the student being edited and the school selected.

Didn’t you create the student in the previous view? By the time you get to this view, it’s no longer a “new” student, it’s an “existing” student.

Sorry - I missed your reply. You’re right. We shouldn’t be saving the form above. Just selecting the school. In any case, I do not see where the student is being created. The form only has the school selection in it.

I’m sorry, I guess I’ve gotten lost among all the different views. If you’re entering the student id on this same form as the filtered course, then you wouldn’t need to query for t.