输入账号的交易模型实现姓名同步和转账

问题描述 投票:0回答:1

我的 Django 应用程序中有以下模型:

class Transaction (models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    account_number = models.IntegerField()
    name = models.CharField(max_length=50)
    amount = models.DecimalField(max_digits=5, decimal_places=2)
    created_on = models.DateTimeField()

class Wallet(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    account_balance = models.DecimalField(max_digits=5, decimal_places=2, default=0)

class AccountNum(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    account_number = models.IntegerField()
    slug = models.SlugField(unique=True)

我想实现一个功能,其中

Transactions
模型中的名称字段根据提供的
account_number
输入与帐户所有者的姓名同步。此外,我想使用当前用户的钱包和
Transactions
模型中的指定金额启用转账。

为了提供一些背景信息,我有一个

post-save
信号
generate_account_number
,它会生成随机的 10 位帐号。

有哪些推荐的技术或方法可以实现名称字段与帐户所有者姓名的

synchronization
,并使用
wallet
模型和
Transaction
模型中的指定金额进行转账?

This is what I have try.

我尝试使用

django-channels
进行同步,但我没有这样做。我试图通过谷歌搜索复制一些人的做法,但我认为我不能单独做到这一点。这是我尝试过的:

consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer
import json
from .models import AccountNum

class TransferConsumers(AsyncWebsocketConsumer):
    async def connect(self):
        await self.connect()

    async def disconnect(self, close_data):
        pass

    async def receive(self, text_data):
        data = json.load(text_data)
        account_number = data['account_number']

        try:
            account = AccountNum.objects.get(account_number=account_number)
            access_name = account.user.username
        except AccountNum.DoesNotExist:
            access_name = 'Name Not found'

路由.py

from django.urls import re_path
from . consumers import TransferConsumers

websocket_urlpatters = [
    re_path('/ws/access/', TransferConsumers.as_asgi()
]

我没有添加模板的原因是需要 JavaScript 代码来实现这一点。我没有 JavaScript 经验,但我想了解更多。

views.py

def make_transfer(request):
    if request.method == 'POST':
        account_number = request.POST.get('account_number')
        name = request.POST.get('name')
        amount = request.POST.get('amount')
    return render(request, 'Profile/make_transfer.html')
python django django-views django-channels banking
1个回答
0
投票

常见问题解答

问:为什么使用UUID而不是RNG(范围内的随机数生成器)(1-10)?

  • 全球唯一:UUID 旨在跨空间和时间全球唯一。
  • 无需集中式 ID 生成:生成保证唯一的随机 10 位数字可能具有挑战性,尤其是在分布式系统中。假设您有 10 亿用户,那么您生成的 id 有十分之一的机会与现有 id 发生冲突,如果用户计数达到 9,999,999,999 ,您的系统将运行这么多次迭代,并将挂起下一个用户。死了。
  • 轻松数据同步:如果您需要在不同数据库或系统之间同步数据,UUID 可以使此过程变得更简单。您不必担心由于重复 ID 导致的冲突,因为 UUID 是全局唯一的。

问:你们好像至少有3个型号,但是规模越大越容易管理吗?

虽然创建模型必须遵循数据库规范化,但在最坏的情况下,太多的表将导致相对较少的用户产生数百万个连接。引入新的改变将是一场噩梦。所以如果你知道 T1 有 (ABC) T2 有 (AD),您可以简单地合并新的优化 T3 (ABCD),从而消除任何连接或缓慢的查询!换句话说,您只需使用 2 个表 USER 和 TRANSACTIONS 即可实现相同的功能,我将在随后解释。

进一步阅读:AbstractUser

设置

pip安装uuid

代码

这里我们做出一些假设,即用户可能没有多个钱包。如果有多个钱包,可以创建您已经创建的另一个钱包模型,但如果钱包用于特定目的且可数,例如“earnings_wallet”、“withdrawal_wallet”或“gifts_wallet”,则只需在模型中再创建一个属性,而不是创建新模型,它将避免对用户(所有者)主键不必要的反向引用。

import uuid  # Import the uuid library

from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # here id is auto generated so no tension for manual random generation
    account_balance = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    
    # wallet and user id are canonicalized so no question of synchronization as they are guranteed to be unique and reference only one entity.
    # any other fields you may have, put here



class Transaction(models.Model):
    # a vary basic model which banks use, may have other fields like, mode of payment (cc, bank transfer) 
    # or something related to tax or any other attribute of the country's financial system
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    sender = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='sent_transactions')
    receiver = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='received_transactions')
    amount = models.DecimalField(max_digits=5, decimal_places=2)
    created_on = models.DateTimeField(auto_now_add=True)
    comments = models.TextField(blank=True)  # Add a comments field

    def __str__(self):
        return f"{self.sender} to {self.receiver}: {self.amount}"

现在如果你想转账给某人,你只需要3个参数发送者,接收者和金额。

注意事项

  • 不要公开此路由,并保留某种形式的 2fa 身份验证或 JWT,因为像会话劫持这样的攻击可能会在用户不通知的情况下执行不需要的交易。浏览器上的一些顽皮的网络扩展可能会造成这种恶作剧。
  • 保持会话过期时间非常低,以减少攻击面
© www.soinside.com 2019 - 2024. All rights reserved.