I'm using a model form and a CBV (createview) to build a form.
I needed to get url parameters into the form so I could access details from the previous view that sent the user to the form. To achieve this I initially tried overriding get_form as follows:
def get_form(self):
form = AddDataForm(key_a=self.request.GET['a'], key_b=self.request.GET['b'])
return form
This didn't work. The form wouldn't save (even when all fields were correctly completed). It would result in an unbound form.
I eventually got a positive result by using get_form_kwargs as follows:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs.update({'key_a': self.request.GET['a'], 'key_b':self.request.GET['b']})
return kwargs
My question is, what about get_form (or my lack of understanding of it) results in this behaviour?
My forms.py is below too.
class AddDataForm(forms.ModelForm):
class Meta:
model = MiningTech
fields = '__all__'
exclude = ('user',)
def __init__(self, key_a, key_b, *args, **kwargs): # key_a comes from the view's get_form.
super(AddDataForm, self).__init__(*args, **kwargs)
if len(key_a) > 3:
for field_name in self.fields:
if not field_name.startswith(key_a[0:3]): # If field_name doesn't start with first 3 characters of key_a, hide it.
self.fields[field_name].widget = forms.HiddenInput()
print("__init__ args", kwargs)
else:
self.fields[field_name].required = True
self.fields['slug'].initial = key_b
else:
print("All fields Hidden")
CodePudding user response:
The ’get_form’ is returning the instance of the form. To initiate the form, the ’get_form_kwargs’ is needed to bind your form to the instance of your model. Even if you create a new instance, the binding is needed to create the instance.
Using ’get_form_kwargs()’ is the right way to add additional argument to the form.