I’m beginning to understand. I actually originally had deposit
and withdraw
variables declared inside the forms.py
class. Here it is with them commented out:
from django import forms
class AmountForm(forms.Form):
amount = forms.DecimalField(label='Amount', max_digits=10, decimal_places=2)
''' deposit = forms.DecimalField(label='Deposit', max_digits=10, decimal_places=2)
withdraw = forms.DecimalField(label='Withdraw', max_digits=10, decimal_places=2)'''
But I get what you are saying now with the deposit/withdraw buttons not being actual fields. These buttons are accessible directly in the request.POST
object. Therefore, I will keep these lines commented out or delete them altogether. I commented out the deposit
and withdraw
references in the form validation check in views.py
, included below.
Based on your feedback, for the two input names, I removed “deposit” and “withdraw” and in their place I now have, “transaction”. Therefore here is what the form in my template looks like now:
<center>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Deposit" name="transaction" >
<input type="submit" value="Withdraw" name="transaction">
</form>
</center>
Next you make a very import suggestion for the correct post request conditional which switches between Deposit
and Withdraw
POST requests:
Keeping that in mind, here is my index function in full now:
def index(request):
# Starting balance variable initialization:
balance = 0
context = {'balance': balance}
# Import `Account` model data:
data = Account.objects.all().order_by('-inception_date')
# If this is a POST request we need to process the form data:
if request.method == 'POST':
# Create a form instance and populate it with data from the request:
form = AmountForm(request.POST)
# Check whether it's valid:
if form.is_valid():
# Process the data in form.cleaned_data as required:
amount = form.cleaned_data['amount']
# deposit = form.cleaned_data['deposit']
# withdraw = form.cleaned_data['withdraw']
if request.POST['transaction'] == 'Deposit':
balance = balance + amount
context.update({'balance': balance,})
if request.POST['transaction'] == 'Withdraw':
balance = balance - amount
context.update({'balance': balance,})
# Redirect to a new URL:
return render(request, 'telagents/home.html', {'form': form, 'data':data, 'context': context,})
# If a GET (or any other method) we'll create a blank form:
else:
form = AmountForm()
return render(request, 'telagents/home.html', {'form': form, 'data':data, })
All of the above integrates @KenWhitesell’s suggestions as best I can and is the latest state of my forms.py
, home.html
(template), and views.py
.
Even witht he above changes, I am now encountering a traceback which points to a data structure Dictionary error like before, but this time it says: MultiValueDictKeyError
. Here is the traceback in full:
Internal Server Error: /
Traceback (most recent call last):
File "/home/<user>/dev/projects/python/2018-and-2020/Django_ATM_OOP_demo/venv/lib/python3.10/site-packages/django/utils/datastructures.py", line 84, in __getitem__
list_ = super().__getitem__(key)
KeyError: 'transaction'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/<user>/dev/projects/python/2018-and-2020/Django_ATM_OOP_demo/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/<user>/dev/projects/python/2018-and-2020/Django_ATM_OOP_demo/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/<user>/dev/projects/python/2018-and-2020/Django_ATM_OOP_demo/telagents/views.py", line 23, in index
if request.POST['transaction'] == 'Deposit':
File "/home/<user>/dev/projects/python/2018-and-2020/Django_ATM_OOP_demo/venv/lib/python3.10/site-packages/django/utils/datastructures.py", line 86, in __getitem__
raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'transaction'
[21/May/2022 10:56:10] "POST / HTTP/1.1" 500 80611
This error highlights line 23 in views.py which is this one:
if request.POST['transaction'] == 'Deposit':
That’s the line that @KenWhiteSell recommended. So I have clearly transcribed it incorrectly and misunderstood.
My understanding is that this line evaluates the condition where if there is a POST request for when the input button named “transaction” and has a value of “Deposit” is triggered by the web visitor. If that condition (antecedent) evaluates to True, then Python proceeds to the next line (to executre the consequent) to perform the mathematical operation (adding the entered amount
into the form to the running balance
) and then finally update the context
variable (a Dictionary). That’s all I got.
What am I missing now?
Thank you Ken for your help and patience so far.