Банковская книга банкоматов на 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
выше я воспользовался официальной документацией Django по созданию форм. - Для создания моего класса
Transactions
я воспользовался официальной документацией Django для моделирования форм.
Вот моя последняя функция 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: