Банковская книга банкоматов на Django - - депозит, снятие, баланс

Я пытаюсь создать элементарный интерактивный прототип бухгалтерской книги банкомата на Python с помощью Django.

Вот как выглядит мое веб-приложение в настоящее время.

Предполагаемая базовая функциональность, которую я пытаюсь создать сейчас, заключается в том, чтобы посетитель сайта (банковский клиент) ввел сумму наличных в поле ввода, а затем нажал: "Депозит" или "Снять". Допустим, клиент вносит $20.00, сумма должна появиться в HTML-таблице в столбце "Кредиты", а столбец "Текущий баланс" должен отражать эту сумму, как это обычно происходит в банкоматах и бухгалтерских книгах. Конечной целью является создание уникальных временных меток и идентификаторов транзакций для каждой транзакции, но сейчас я сосредоточен на том, чтобы переменная "Текущий баланс" (самый правый столбец) обновлялась, когда посетитель сайта вводит сумму и нажимает кнопку "Депозит". В настоящее время, когда веб-посетитель вводит $20.00 в качестве суммы в поле, а затем нажимает "Депозит", поскольку у меня есть оператор печати внутри моего views.py, терминал Django показывает: <QueryDict: {'csrfmiddlewaretoken': ‘<redacted>'], 'amount': ['20.00'], 'transaction': ['Deposit']}>. Таким образом, сумма принимается и обрабатывается. Но Текущий баланс остается $0.00, что я и пытаюсь решить.

forms.py:

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)

views.py:

from django.shortcuts import render
from django.http import HttpResponseRedirect,HttpResponse
from .models import Account, Transactions
# 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:
   print(request.POST)
   if request.method == 'POST':
       # Create a form instance and populate it with data from the request:
       form = Transactions(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']
           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, })

models.py:

from django.db import models
from datetime import datetime
# from pytz import timezone
import decimal
from decimal import Decimal
from random import randint
from django.forms import ModelForm
from telagents.forms import AmountForm
 
class Account(models.Model):
   #### Static data elements :
   interest = models.DecimalField(max_digits=6, decimal_places=3) # Percent
   inception_date = models.DateTimeField('Client since (inception date)')
   first_name = models.CharField(max_length=30)
   last_name = models.CharField(max_length=30)
   account_number = models.BigIntegerField()
   #### Interactive and dynamic data points :
   debit = models.DecimalField(max_digits=12, decimal_places=2)
   credit = models.DecimalField(max_digits=12, decimal_places=2)
   balance = models.DecimalField(max_digits=12, decimal_places=2)
   amount = models.DecimalField(max_digits=12, decimal_places=2)
   trans_timestamp = models.DateTimeField(auto_now=False, auto_now_add=False)
   trans_id = models.BigIntegerField()
 
   def client_since(self):
       # a = self.pub_date.timezone.now("US")
       # b = pytz.timezone("US")
       return self.inception_date.strftime("%A %d %B %Y @ %I:%M:%S %p")
  
   def __str__(self):
       return f"{self.first_name} {self.last_name}'s bank account."
 
class Transactions(ModelForm):
   class Meta:
       model = Account
       fields = ['amount',]

Как вы можете видеть в нижней части файла models.py выше, я пытаюсь использовать ModelForm. Единственным полем является сумма. Для переменной класса модели я использую Account, который, в свою очередь, наследует свойства определенного над ним класса Account через полиморфизм. Но это не совсем то, что я пытаюсь сделать. Вместо этого я хочу наследовать свойство amount, определенное в классе AmountForm, как определено в forms.py. Но когда я изменяю Account на AmountForm, Django выдает ошибку: AttributeError: type object 'AmountForm' has no attribute '_meta'

templates/home.html:

<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>
 
<center>
<table class="GeneratedTable">
  <thead>
   <tr>
     <th>Type</th>
     <th>Timestamp</th>
     <th>Trans ID #</th>
     <th>Merchant</th>
     <th>Debits</th>
     <th>Credits</th>
     <th>Running Balance</th>
   </tr>
 </thead>
  <tbody>
   <tr>
   {% for trans_objs in data %}
     <td>(null)</td>           
     <td>{{ trans_objs.trans_timestamp }}</td>     
     <td>{{ trans_objs.trans_id }}</td>     
     <td>Big Bank ATM</td>
     <td>{{ trans_objs.debit }}</td>
     <td>{{ trans_objs.credit }}</td>     
     <td>{{ trans_objs.balance }} </td>
   {% endfor %}    
   </tr>
 </tbody>
  <tbody>
   <tr>
   {% for trans_objs in context %}
     <td>(null)</td>           
     <td>(null)</td>     
     <td>(null)</td>     
     <td>ATM</td>
     <td>(null)</td>
     <td>(null)</td>     
     <td>{{ trans_objs.amount }} </td>
   {% endfor %}    
   </tr>
 </tbody>
 
</table>
</center>

Как вы можете видеть здесь, у меня есть две строки внутри циклов Jinja for. Первый просто позиционирует статическую информацию. В основном это просто заполнители. Все эти данные вводятся в панели администратора. Это статические данные. Во втором ряду - моя лучшая попытка экстраполировать переменную balance из словаря context в словарь views.py динамически. Но это не работает. Она пуста, как вы можете видеть на скриншоте, которым я поделился в начале этого вопроса.

Что мне нужно изменить в моем views.py, чтобы заставить Django принимать ввод формы пользователя в моем шаблоне для выполнения простой математической операции добавления суммы к балансу, введенному пользователем, и последующего ее обновления в HTML-таблице?

Ресурсы, которые я использовал до сих пор:

Вот моя последняя функция views.py:

def index(request):
   balance = 0
   context = {'balance': balance}
   data = Account.objects.all() 
   myaccount = Account.objects.get(id=1)
   print(request.POST)
   if request.method == 'POST':
       form = Transactions(request.POST)
       if form.is_valid():
           print(form)
           amount = form.cleaned_data['amount']
           if request.POST['transaction'] == 'Deposit':
               balance = balance + amount
               context.update({'balance': balance,})
           if request.POST['transaction'] == 'Withdraw':
               balance = balance - amount
               context.update({'balance': balance,})
           myaccount.balance = balance
           myaccount.save()
           return render(request, 'telagents/home.html', {'form': form, 'data':data, 'context': context,})
 
   else:
       form = AmountForm()
 
   return render(request, 'telagents/home.html', {'form': form, 'data':data, })

Решающим изменением выше является инстанцирование объекта класса Account при инициализации с запросом .get, установленным на единственную запись строки id в базе данных. Затем я обращаюсь к этому объекту в конце алгоритма, где я применяю входной баланс, собранный из запроса POST, к атрибуту баланса и затем сохраняю его в myaccount.

Цитирую мой первоначальный вопрос:

Вместо этого я хотел, чтобы баланс динамически изменялся каждый раз, когда посетитель сайта вносит депозит или снимает деньги.

Итак, я выполнил то, что намеревался сделать в своем вопросе выше. Под этим я подразумеваю, что когда веб-посетитель заходит на веб-страницу сейчас, вводит сумму в долларах и нажимает "Депозит", поле баланса в бухгалтерской книге обновляется, отражая введенную сумму.

Следующая проблема, которую необходимо решить, заключается в том, что алгоритм моей функции views.py не отслеживает текущий баланс при последующих депозитах. Когда посетитель сайта вводит вторую сумму депозита, он просто перезаписывает прежний баланс. Следующий шаг, который я должен сделать, - исправить это.

Мне помог друг придумать мой пересмотренный views.py, но я доработал его, основываясь на бесплатном мини-курсе , который учит, как сначала использовать утилиту GUI sqlite browser, а затем переходит к рассмотрению запросов к db.sqlite3 из Python REPL, интегрированного с базовым тестовым проектом Django. Курс ссылается на документацию Django:

Вернуться на верх