Reputation: 67
I'm trying to learn Django and am finding it frustratingly difficult to do fairly basic things. I have the following form classes:
from django import forms
class InputForm(forms.Form):
field1 = forms.FloatField(label="First field: ")
field2 = forms.FloatField(label="Second field: ")
class OutputForm(forms.Form):
outfield = forms.FloatField(label="Result: ")
And the following template:
<form>
{{ input_form.as_ul }}
<input type="submit" class="btn" value="Submit" name="submit_button">
</form>
<form>
{{ output_form.as_ul }}
</form>
And finally, the following view:
from django.shortcuts import render
from .forms import InputForm, OutputForm
def index(request):
if request.GET.get('submit_button'):
# ?????
else:
input_form = InputForm()
output_form = OutputForm()
return render(request, 'index.html', {'input_form': input_form,
'output_form': output_form})
All I want to happen is that when I hit the submit button, the values in first field and second field get added and displayed in the result field. I know from debug outputs that the ????? commented block is run when I press the button, but I have so far not been able to figure out what to do to actually access or alter the data in my fields. I don't care about keeping a record of these transactions so it feels like storing these in a database is tremendous overkill. What is the correct way to approach this?
Upvotes: 2
Views: 630
Reputation: 308959
You don't need a form to display the result. When the form is valid, you can get the values from the form's cleaned_data
and calculate result
.
def index(request):
result = None # Set to None by default
if request.GET.get('submit_button'): # The submit button was pressed
input_form = InputForm(request.GET) # Bind the form to the GET data
if input_form.is_valid():
result = input_form.cleaned_data['field1'] + input_form.cleaned_data['field2'] # Calculate the result
else:
input_form = InputForm() # Submit button was not pressed - create an unbound (blank) form
return render(request, 'index.html', {'input_form': input_form, result:result})
Then in your template, include {{ result }}
instead of the output form.
Upvotes: 0
Reputation: 2688
Setting the initial poperty on a field prefills it:
output_form.fields['outfield'].initial = input_form.data.get ('field1') + input_form.data.get ('field1')
You need to pass request.POST or request.GET into OutputForm when you instantiate it. You should also be calling is_valid() on the from and using cleaned_data instead of data after you check if it is valid.
Upvotes: 0
Reputation: 6190
There's a few things at work here, lets go through them one by one.
1. Calculating the output value
Use the request data to build the form, validate it, and then calculate the sum:
if request.GET.get('submit_button'):
input_form = InputForm(request.GET)
if input_form.is_valid():
data = input_form.cleaned_data
result = data["field1"] + data["field2"]
2. Read-only output
It's not clear why you're using a submittable form field for data that is to be calculated by your app, as opposed to playing the result into a regular html 'label' in the template. If you really want/need to set the result in a form field, I'd at least make it read-only. See In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited? for an example of how to do that.
3. Set the output data in the form
Set the output form/field's initial
data to the result you have calculated. following on form the code at (1):
result = data["field1"] + data["field2"]
output_form = OutputForm(initial={"outfield": result})
then render the view as you're already doing:
return render(
request,
'index.html',
{'input_form': input_form, 'output_form': output_form},
)
Upvotes: 1