Python Forum
ATM machine demo with Python and Django
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ATM machine demo with Python and Django
#2
Hello, Friends!

I reviewed the Django docs on forms. In particular I leveraged the sections on views and on field data. Following along with these docs closely and based on what I learned, I rebuilt my codebase. I created forms.py and completely rewrote both my template and views.py from scratch. Now I am getting a key error. I figure the solution I need is far more trivial today than last week but at this point I am basing my head against the wall and stabbing in the dark.

I’ll share my code, along with the traceback and explain what I think is going on which hopefully will be enough for you people to recommend what I could try next.

forms.py:
from django import forms

class AmountForm(forms.Form):
    amount = forms.DecimalField(label='Amount', max_digits=10, decimal_places=2)
As you can see above, there is only one field I’ve declared: amount. This is the only information the web visitor can input when they visit the site. My form has two input buttons (‘Withdraw’ and ‘Deposit’) but when they are pressed by the web visitor, Django redirects the amount value back for processing by the views (below) which should then in turn store it in the database and then be presented back to the web visitor with an updated balance variable in the table when Django re-serves the template.

views.py:
from django.shortcuts import render
from django.http import HttpResponseRedirect,HttpResponse
from .models import Account
# Create your views here.
from .forms import AmountForm

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:
            deposit = form.cleaned_data['deposit']
            withdraw = form.cleaned_data['withdraw']
            amount = form.cleaned_data['amount']
            if deposit:
                balance = balance + amount
                context.update({'balance': balance,})
            elif withdraw:
                balance = balance - withdraw
                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, })
As you can see in the above views, I’ve retained and added annotations line-by-line to help document what is going on. When Django checks for the validity of the form, assuming it is valid, received (and cleaned) data (deposit, withdraw, amount) is assigned to variables. If deposit is triggered, then the basic mathematical operation takes place (increase the size of balance by the amount entered by the web visitor). And then I attempt to update the context dictionary variable with the new balance amount. Finally, the request is rendered for the home template while passing in the form, data, and context information. That’s ‘air tight’. That’s my very best effort up to this point at rewriting a proper views.py based on the documentation.

templates/telagents/home.html:
Quote: <body>
{% block content %}

<br><br>

{% for data_obj in data %}
<center>
Client Name : {{data_obj.first_name}} {{data_obj.last_name}}
<br>
Bank Account Number : {{data_obj.account_number}}
<br>
Client Since : {{ data_obj.inception_date }}
<br>
Interest Rate : {{data_obj.interest}} %
</center>
{% endfor%}

<br><br>

<center>
<form action="{% url 'index' %}" method="post">

{% csrf_token %}
{{ form }}
<input type="submit" value="Deposit" name="deposit" >
<input type="submit" value="Withdraw" name="withdraw">
</form>
</center>
<br>

<center>
<table class="GeneratedTable">
<thead>
<tr>
<th>Type</th>
<th>Timestamp</th>
<th>Trans ID #</th>
<th>Debits</th>
<th>Credits</th>
<th>Running Balance</th>
</tr>
</thead>
<tbody>
<tr>
{% for trans_objs in context %}
<td>Cell</td>

<td>Cell</td>

<td>Cell</td>

<td>{{ trans_objs.withdraw }}</td>

<td>{{ trans_objs.deposit }}</td>

<td>{{ trans_objs.balance }} </td>
{% endfor %}
</tr>
</tbody>
</table>

</center>

{% endblock %}

</body>

As you can see above, I’ve used Django’s very easy and convenient instance of {{ form }} for easy deployment of HTML forms. I’ve got the CSRF token in place. I’ve got the two input tags for the withdraw and deposit buttons. Finally in the table, I’ve completely reworked the Jinja for loop to output the withdraw, deposit, and balance data points.

Here is my traceback:

Error:
System check identified no issues (0 silenced). May 20, 2022 - 17:36:04 Django version 4.0.4, using settings 'Django_ATM_OOP_demo.settings' Starting development server at http://localhost:9000/ Quit the server with CONTROL-C. 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/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 20, in index deposit = form.cleaned_data['deposit'] KeyError: 'deposit'
This error is pointing to line 20 of my views.py where the deposit variable is declared referencing where Django is trying to extrapolate the deposit information as cleaned_data. That’s all I understand about that.

This is the point where I ask for insight from the community.

What else is this traceback trying to say?

I suppose a good question for me to ask is which Django doc do I need to review next? Although I may be just missing a specific passage from the same Django doc on forms I leveraged earlier that I can review again.

Is there any advice you people could provide in terms of what I might need to change in my template, views, or forms to resolve this KeyError and enable my web app to properly process the data entry made by my web visitors?

For what it is worth and for those who may be interested, here is the full source code on GitHub (working branch).
Reply


Messages In This Thread
RE: ATM machine demo with Python and Django - by Drone4four - May-20-2022, 06:34 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Django: How to automatically substitute a variable in the admin page at Django 1.11? m0ntecr1st0 3 3,528 Jun-30-2019, 12:21 AM
Last Post: scidam
  python-forum.io on way back machine metulburr 1 3,065 Jan-13-2019, 03:52 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020