I have the following models in my Django application:
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)
I want to implement a feature where the name field in the Transactions
model gets synchronized with the account owner's name based on the provided account_number
input. Additionally, I want to enable money transfers using the current user's wallet and the specified amount in the Transactions
model.
To provide some context, I have a post-save
signal generate_account_number
which generates a random 10-digit account number.
What are some recommended techniques or approaches to achieve this synchronization
of the name field with the account owner's name and enable money transfers using the wallet
model and specified amount in the Transaction
model?
Even though I failed to implement an account name based on a given account number, I'm happy to share the way we can send money from one account to another.
The technical way to do so is by creating only two models, Account
and Transaction
models, and adding what is in the Wallet
model to an Account
model like this:
class Account(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
account_number = models.IntegerField()
account_balance = models.DecimalField(max_digits=12, decimal_places=6)
To send fund from one account to another, we have to create sender
and receiver
field and assign them to a CustomUser
model with different related_name
in the Transaction
model, just like this:
import random
def generate_random_number():
return random.randint(1, 30)
class Transaction(models.Model):
amount = models.DecimalField(max_digits=12, decimal_places=6)
sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='transfer_sents')
receiver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='transfer_receives')
account_number = models.IntegerField()
name = models.CharField(max_length=50)
refrence_number = models.CharField(max_length=50, default=generate_random_number)
I've written a Django view function that's designed to handle financial transactions. Let me break down how it works:
The view takes the amount
and name
values from the submitted form data, and it retrieves the sender
and receiver
account objects from the database using the Account
model. The sender account is associated with the currently logged-in user, while the receiver account is identified by the account_number
provided in the form data, and then ensure there are sufficient funds, the view checks if the sender account balance can cover the transaction amount. If it can, the view deducts the 'amount' from the sender account balance and increases the receiver account balance by the same 'amount'. These changes are then saved to the database. In the event of insufficient funds in the sender account, the view generates an error message using Django messaging framework. The user is then redirected to that page.
views.py
from decimal import Decimal
from django.contrib import messages
def create_transfer(request):
if request.method == 'POST':
amount = Decimal(request.POST.get('amount'))
name = request.POST.get('name')
sender_account = Account.objects.get(user=request.user)
receiver_account = Account.objects.get(account_number=request.POST.get('account_number'))
if sender_account.account_balance >= amount:
sender_account.account_balance -= amount
sender_account.save()
receiver_account.account_balance += amount
receiver_account.save()
Transaction.objects.create(
sender=sender_account.user,
receiver=receiver_account.user,
amount=amount,
name=name,
account_number=receiver_account
)
else:
messages.error(request, 'Insufficient Funds')
return redirect('Transaction')
return render(request, 'create_transfer.html')