Django set field value after a form is initialized

Django

Django Problem Overview


I am trying to set the field to a certain value after the form is initialized.

For example, I have the following class.

class CustomForm(forms.Form):
	Email = forms.EmailField(min_length=1, max_length=200)

In the view, I want to be able to do something like this:

form = CustomForm()
form["Email"] = GetEmailString()

return HttpResponse(t.render(c))

Django Solutions


Solution 1 - Django

Since you're not passing in POST data, I'll assume that what you are trying to do is set an initial value that will be displayed in the form. The way you do this is with the initial keyword.

form = CustomForm(initial={'Email': GetEmailString()})

See the Django Form docs for more explanation.

If you are trying to change a value after the form was submitted, you can use something like:

if form.is_valid():
    form.cleaned_data['Email'] = GetEmailString()

Check the referenced docs above for more on using cleaned_data

Solution 2 - Django

If you've already initialized the form, you can use the initial property of the field. For example,

form = CustomForm()
form.fields["Email"].initial = GetEmailString()

Solution 3 - Django

If you want to do it within the form's __init__ method for some reason, you can manipulate the initial dict:

class MyForm(forms.Form):
    my_field = forms.CharField(max_length=255)

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.initial['my_field'] = 'Initial value'

Solution 4 - Django

Something like Nigel Cohen's would work if you were adding data to a copy of the collected set of form data:

form = FormType(request.POST)
if request.method == "POST":
    formcopy = form(request.POST.copy())
    formcopy.data['Email'] = GetEmailString()

Solution 5 - Django

If you have initialized the form like this

form = CustomForm()

then the correct way as of Jan 2019, is to use .initial to replace the data. This will replace the data in the intial dict that goes along with the form. It also works if you have initialized using some instance such as form = CustomForm(instance=instance)

To replace data in the form, you need to

form.initial['Email'] = GetEmailString()

Generalizing this it would be,

form.initial['field_name'] = new_value

Solution 6 - Django

Just change your Form.data field:

class ChooseProjectForm(forms.Form):
    project = forms.ModelChoiceField(queryset=project_qs)
    my_projects = forms.BooleanField()

    def __init__(self, *args, **kwargs):
        super(ChooseProjectForm, self).__init__(*args, **kwargs)
        self.data = self.data.copy()  # IMPORTANT, self.data is immutable
        # any condition:
        if self.data.get('my_projects'):
            my_projects = self.fields['project'].queryset.filter(my=True)
            self.fields['project'].queryset = my_projects
            self.fields['project'].initial = my_projects.first().pk
            self.fields['project'].empty_label = None  # disable "-----"
            self.data.update(project=my_projects.first().pk)  # Update Form data
            self.fields['project'].widget = forms.HiddenInput()  # Hide if you want

Solution 7 - Django

To throw yet another way into the mix: this works too, with a bit more modern notation. It just works around the fact that a QueryDict is immutable.

>>> the_form.data = {**f.data.dict(), 'some_field': 47}
>>> the_form['some_field'].as_widget()
'<input type="hidden" name="some_field" value="47"
        class="field-some_field" id="id_some_field">'

Solution 8 - Django

in widget use 'value' attr. Example:

username = forms.CharField(
    required=False,
    widget=forms.TextInput(attrs={'readonly': True, 'value': 'CONSTANT_VALUE'}),
)

Solution 9 - Django

Another way to do this, if you have already initialised a form (with or without data), and you need to add further data before displaying it:

form = Form(request.POST.form)
form.data['Email'] = GetEmailString()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEldilaView Question on Stackoverflow
Solution 1 - DjangoGrantView Answer on Stackoverflow
Solution 2 - DjangoJoshView Answer on Stackoverflow
Solution 3 - DjangoseddonymView Answer on Stackoverflow
Solution 4 - DjangoMilo PView Answer on Stackoverflow
Solution 5 - DjangoVineeth SaiView Answer on Stackoverflow
Solution 6 - DjangockarrieView Answer on Stackoverflow
Solution 7 - Djangodr. SybrenView Answer on Stackoverflow
Solution 8 - DjangoLucas VazquezView Answer on Stackoverflow
Solution 9 - DjangoNigel CohenView Answer on Stackoverflow