I want to pass self.request
data in the form class. I can access it in View, but unable to access it in form class.
class AttendanceCreateView(LoginRequiredMixin, CreateView):
model = Attendance
template_name = 'attendance/attendances_new.html'
form_class = AttendanceForm
def get_initial(self):
initial = super().get_initial()
initial['class_name'] = self.request.GET.get('class', '')
return initial
My Form class:
class AttendanceForm(forms.ModelForm):
class_name = forms.ChoiceField(choices=CLASS_NAMES, disabled=True)
teacher = forms.ModelMultipleChoiceField(
queryset=Teacher.objects.all().order_by('id'))
subject_name = forms.ChoiceField(choices=[])
total_students = forms.IntegerField(initial=0)
unique_code = forms.IntegerField(initial=0)
class Meta:
model = Attendance
fields = ['class_name', 'teacher', 'subject_name',
'total_students', 'unique_code']
def __init__(self, *args, **kwargs):
super(AttendanceForm, self).__init__(*args, **kwargs)
# This I need to be done
# if self.request.GET.get('class', '') = 'class1':
# self.fields['subject_name'].choices = MY_CHOICES_1
# elif self.request.GET.get('class', '') = 'class2':
# self.fields['subject_name'].choices = MY_CHOICES_2
I want to set subject_name
choices according to the request values passed. For class 1, I want different subject choices., and for class 2, different subject choices etc. So getting request data is important.
Is there any way to set the initial choice in direct View like I did for class_name
? Or any suggestions on how to do it in form?
Pass the request through the form_kwargs
:
class AttendanceCreateView(LoginRequiredMixin, CreateView):
model = Attendance
template_name = 'attendance/attendances_new.html'
form_class = AttendanceForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_initial(self):
initial = super().get_initial()
initial['class_name'] = self.request.GET.get('class', '')
return initial
and then we handle this in the form:
class AttendanceForm(forms.ModelForm):
# …
def __init__(self, *args, request, **kwargs):
self.request = request
super().__init__(*args, **kwargs)
if self.request.GET.get('class', '') == 'class1':
self.fields['subject_name'].choices = MY_CHOICES_1
elif self.request.GET.get('class', '') == 'class2':
self.fields['subject_name'].choices = MY_CHOICES_2
Note: Since PEP-3135 [pep], you don't need to call
super(…)
with parameters if the first parameter is the class in which you define the method, and the second is the first parameter (usuallyself
) of the function.