简体   繁体   English

Django中的银行ATM分类帐--存款,取款,余额

[英]Bank ATM ledger in Django - - deposit, withdrawal, balance

I'm trying to build a rudimentary interactive ATM machine ledger prototype demo in Python with Django.我正在尝试使用 Django 在 Python 中构建一个基本的交互式 ATM 机分类帐原型演示。

Here is what my web app currently looks like .这是我的网络应用程序当前的样子

The intended basic functionality I am trying to create right now is to have the web visitor (banking client) enter the amount of cash in the input field and then click: “Deposit” or ”Withdraw”.我现在尝试创建的预期基本功能是让网络访问者(银行客户)在输入字段中输入现金金额,然后单击:“存款”或“取款”。 Say for example the client deposits $20.00, the amount should appear in the HTML table under the “Credits” column and the “Running Balance” column should reflect that as well, like anyone would expect a typical ATM and accounting ledger to behave.例如,客户存入 20.00 美元,该金额应出现在 HTML 表格中的“信用”列下,“流动余额”列也应反映这一点,就像任何人都希望典型的 ATM 和会计分类账的行为一样。 The end goal is to have unique timestamps and transaction IDs to generate with each transaction, but for now I am focused on just getting the 'running balance' variable (rightmost column) to update when the web visitor inputs an amount and clicks “Deposit”.最终目标是为每笔交易生成唯一的时间戳和交易 ID,但现在我只关注在网络访问者输入金额并单击“存款”时更新“运行余额”变量(最右边的列) . Currently, when a web visitor enters $20.00 as the amount in the box and then clicks “Deposit”, since I've got a print statement inside my views.py , the Django terminal shows: <QueryDict: {'csrfmiddlewaretoken': '<redacted>'], 'amount': ['20.00'], 'transaction': ['Deposit']}> .目前,当网络访问者在框中输入 $20.00 作为金额然后单击“存款”时,由于我的views.py中有一个打印语句,Django 终端显示: <QueryDict: {'csrfmiddlewaretoken': '<redacted>'], 'amount': ['20.00'], 'transaction': ['Deposit']}> . So an amount is being accepted and processed.因此,正在接受和处理金额。 But the Running Balance remains $0.00, which is what I am trying to solve.但是运行余额仍然是 0.00 美元,这是我要解决的问题。

forms.py :表格.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 :视图.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 :模型.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',]

As you can see at the bottom of the models.py above, I attempt to use a ModelForm .正如您在上面的 models.py 底部看到的那样,我尝试使用ModelForm The only field is amount.唯一的字段是金额。 For the model class variable, I use Account which in turn inherits the properties of the Account class defined above it through polymorphism.对于模型类变量,我使用Account ,它又通过多态性继承了上面定义的Account类的属性。 But this isn't really what I am trying to do.但这并不是我真正想要做的。 Instead I wish to actually inherit the amount property defined in the AmountForm class as defined in forms.py .相反,我希望实际继承在 forms.py 中定义的AmountForm类中定义的amount forms.py But when I change Account to AmountForm , Django throws an error saying : AttributeError: type object 'AmountForm' has no attribute '_meta'但是当我将Account更改为AmountForm时,Django 会抛出一个错误: AttributeError: type object 'AmountForm' has no attribute '_meta'

templates/home.html :模板/home.html

 <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="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>

{% endblock %}

</body>

As you can see here, I've got two rows within Jinja for loops.正如你在这里看到的,我在 Jinja 中有两行 for 循环。 The first one just positions static information.第一个只是定位静态信息。 Those are mostly just placeholders.这些大多只是占位符。 All that data showing is entered in the Admin Dashboard.所有显示的数据都输入到管理仪表板中。 It's static.它是静态的。 In the second row is my best attempt at extrapolating the balance variable from the context dictionary in the views.py dynamically.第二行是我从views.py中的context字典动态推断balance变量的最佳尝试。 But it doesn't work.但它不起作用。 It's empty as you can see in the screenshot I shared way at the top of this question.正如我在这个问题顶部分享的屏幕截图中所看到的那样,它是空的。

What do I need to change in my views.py to get Django to accept user form input in my template to complete the simple mathematical operation of adding the amount to the balance entered by the user and then having it updated in the HTML table?我需要在我的views.py中进行哪些更改才能让Django 在我的模板中接受用户表单输入,以完成将金额添加到用户输入的余额然后在HTML 表中更新的简单数学运算?

Resources I've used so far:到目前为止我使用过的资源:

Here is my latest views.py function:这是我最新的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, })

The crucial changes above is the instantiation of the Account class object during initialization with the .get query set to the only id row entry in the db.上面的关键更改是在初始化期间实例化Account类对象,其中.get查询设置为数据库中唯一的id行条目。 I then refer to this object towards the end of the algorithm where I apply the balance input collected from the POST request to the balance attribute and then save it to myaccount .然后我在算法结束时引用这个对象,我将从POST请求收集的余额输入应用到 balance 属性,然后将其保存到myaccount

To quote my original question:引用我原来的问题:

Instead I was intending to have the balance change dynamically every time a web visitor makes a deposit or withdrawal.相反,我打算在每次网络访问者进行存款或取款时动态更改余额。

So I accomplished what I intended to in my question above.所以我完成了我在上面的问题中的意图。 By that I mean, when a web visitor lands on the web page now and they enter a dollar amount and click “Deposit”, the balance field in the ledger updates to reflect the amount entered.我的意思是,当网络访问者现在登陆网页并输入美元金额并单击“存款”时,分类帐中的余额字段会更新以反映输入的金额。

The problem to solve next is that my views.py function algorithm doesn't track a running tally with subsequent deposits.接下来要解决的问题是,我的 views.py 函数算法不会跟踪后续存款的运行记录。 When a web visitor enters a second deposit amount, it just overwrites the former balance.当网络访问者输入第二笔存款金额时,它只会覆盖之前的余额。 The next step for me to take is to fix this.我要采取的下一步是解决这个问题。

I had help from a friend to come up with my revised views.py but I refined it further based on a free mini crash course which teaches how to first use a GUI sqlite browser utility and then proceeds to cover querying db.sqlite3 from Python REPL integrated with a basic Django test project.我在朋友的帮助下提出了修改后的 views.py,但我根据 免费的迷你速成课程进一步完善了它,该课程教授如何首先使用 GUI sqlite 浏览器实用程序,然后继续介绍从 Python REPL 查询 db.sqlite3与基本的 Django 测试项目集成。 The course refers to Django docs:本课程参考 Django 文档:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM