With this form:
class Form(forms.Form):
name = forms.CharField(required=False, initial='Hello world')
If I do something like this in the view:
form = Form(request.GET)
if form.is_valid():
name = form.cleaned_data['name']
Then initial value of name is lost even if request.GET does not contain name
as key. Is there any workaround? I would like initial values work to bound forms as "default values".
request.GET
is a dictionary like object.
initial
only works in case of unbound form.
Forms have an attribute named data
. This attribute is provided as first positional argument or as a data
keyword argument during form initialization.
Bound forms are those in which you provide some data as first argument to the form and unbound form has data
attribute set as None.
Here in your initialization of form form=Form(request.GET)
, you are providing the first positional argument, so data
attribute is being set on the form and it becomes a bound form. This happens even if request.GET
is an empty dictionary. And since your form becomes a bound form so initial
of name
field has no effect on it.
So, In you GET request you should either do:
form = Form()
and your initial
of name
field would be honoured.
Or, if you want to read name
from request.GET and if its there then want to use it instead of field's initial then have following in your view.
name = request.GET.get(name)
form_level_initial = {}
if name:
form_level_initial['name'] = name
form = Form(initial=form_level_initial)
By slightly modifying Gonzalo's solution, this is the right way:
class Form(forms.Form):
name = forms.CharField(required=False, initial='Hello world')
def clean_name(self):
if not self['name'].html_name in self.data:
return self.fields['name'].initial
return self.cleaned_data['name']
If you need this, you may have a look at django-filter app. I have discovered it quite recently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With