I am trying to withdraw some amount from my investment using the line of code below the account balance is not updating after withdrawal.
investment.basic_investment_return -= investment.basic_withdraw_amount
Model
from django.db import models
class Investment(models.Model):
basic_deposit_amount = models.IntegerField(default=0, null=True)
basic_interest = models.IntegerField(default=0, null=True)
basic_investment_return = models.IntegerField(default=0, null=True)
basic_withdraw_amount = models.IntegerField(default=0, null=True, blank=True)
basic_balance = models.IntegerField(default=0, null=True, blank=True)
investment_id = models.CharField(max_length=10, null=True, blank=True)
is_active = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now=True, null=True)
def save(self, *args, **kwargs):
self.basic_interest = self.basic_deposit_amount * 365 * 0.02/2
self.basic_investment_return = self.basic_deposit_amount self.basic_interest
super(Investment, self).save(*args, **kwargs)
Forms
from django import forms
from .models import Investment
class BasicInvestmentForm(forms.ModelForm):
class Meta:
model = Investment
fields = ['basic_deposit_amount']
class BasicWithdrawalForm(forms.ModelForm):
class Meta:
model = Investment
fields = ['basic_withdraw_amount']
Views
from django.shortcuts import get_object_or_404, redirect, render
from django.db.models import Sum, F
from django.contrib import messages
from .forms import BasicInvestmentForm, BasicWithdrawalForm,
from .models import Investment,
def create_investment_view(request):
if request.method == 'POST':
basic_investment_form = BasicInvestmentForm(request.POST)
if basic_investment_form.is_valid():
investment = basic_investment_form.save(commit=False)
investment.basic_investment_return = investment.basic_deposit_amount
print(investment.basic_investment_return)
investment.is_active = True
investment.save()
messages.success(request, 'your basic investment of {} is successfull '.format(investment.basic_deposit_amount))
else:
messages.success(request, 'your investment is not successfull! Try again.')
else:
basic_investment_form = BasicInvestmentForm()
context = {'basic_investment_form': basic_investment_form}
return render(request, 'create-basic-investment.html', context)
def create_withdrawal_view(request):
if request.method == 'POST':
basic_withdraw_form = BasicWithdrawalForm(request.POST)
if basic_withdraw_form.is_valid():
investment = basic_withdraw_form.save(commit=False)
investment.basic_investment_return -= investment.basic_withdraw_amount
print(investment.basic_investment_return)
investment.save()
messages.success(request, 'your withdrawal of {} is successfull '.format(investment.basic_withdraw_amount))
else:
messages.success(request, 'your withdrawal of {} is unsuccessfull '.format(investment.basic_withdraw_amount))
else:
basic_withdraw_form = BasicWithdrawalForm()
context = {'basic_withdraw_form': basic_withdraw_form}
return render(request, 'create-basic-withdrawal.html', context)
I can see the value of
print(investment.basic_investment_return)
in console but I noticed the result is always the deducted value.
CodePudding user response:
investment.basic_investment_return is always going to be zero to start with, because you never set it.
When you call
investment = basic_withdraw_form.save(commit=False)
you create an investment instance based on the form, which has a single field, 'basic_withdraw_amount'. 'basic_investment_return' isn't provided so it will therefore always be its default value, which is 0:
investment.basic_investment_return -= investment.basic_withdraw_amount
print(investment.basic_investment_return)
#is the same as 0 - basic_withdraw_amount
#BUT ONLY at point of print()
In the save function, you essentially overwrite the value you print() by setting
self.basic_investment_return = self.basic_deposit_amount self.basic_interest
Currently the value you set in the view (the printed value) isn't being recorded, it only exists in the instance 'investment' briefly until the save function overrides it, both in the instance and the version saved to the database.
CodePudding user response:
Editing my answer since there are new information given below and the post has been updated:
You're expecting investment.basic_investment_return
to have the value equal to the computation in your Investment save method. This will not work because the save method will only execute in investment.save()
, which means:
# if the user passes 10 for basic_deposit_amount, the computation
# below is actually 0 = 0 10
investment.basic_investment_return = investment.basic_deposit_amount
Adding print lines like so will verify this:
models
def save(self, *args, **kwargs):
print(f"Model basic_deposit_amount: {self.basic_deposit_amount}")
self.basic_interest = self.basic_deposit_amount * 365 * 0.02/2
print(f"Model basic_interest: {self.basic_interest}")
self.basic_investment_return = self.basic_deposit_amount self.basic_interest
print(f"Model basic_investment_return: {self.basic_investment_return}")
super(Investment, self).save(*args, **kwargs)
create_investment_view
print(f"Form basic_investment_return: {investment.basic_investment_return}")
investment.basic_investment_return = investment.basic_deposit_amount
print(f"Computed basic_investment_return: {investment.basic_investment_return}")
The terminal will display the following:
Form basic_investment_return: 0
Computed basic_investment_return: 10
Model basic_deposit_amount: 10
Model basic_interest: 36.5
Model basic_investment_return: 46.5
If you intend to use the computation in your save method for both create_investment_view
and create_withdrawal_view
, I suggest you move it outside the class like so:
models
# outside Investment
def compute_basic_interest_and_return(basic_deposit_amount):
basic_interest = basic_deposit_amount * 365 * 0.02/2
basic_investment_return = basic_deposit_amount basic_interest
return (basic_interest, basic_investment_return)
views
from .models import compute_basic_interest_and_return
def create_investment_view(request):
...
(basic_interest, basic_investment_return) = compute_basic_interest_and_return(
investment.basic_deposit_amount
)
investment.basic_interest = basic_interest
investment.basic_investment_return = basic_investment_return
investment.basic_investment_return = investment.basic_deposit_amount
...
def create_withdrawal_view(request):
...
(basic_interest, basic_investment_return) = compute_basic_interest_and_return(
investment.basic_deposit_amount
)
investment.basic_interest = basic_interest
investment.basic_investment_return = basic_investment_return
investment.basic_investment_return -= investment.basic_withdraw_amount
...
Above is just a sample but I hope you understood the point. Note that you will also need to pass a value for basic_deposit_amount
in your create_withdrawal_view
, so update your BasicWithdrawalForm fields.
CodePudding user response:
I fixed it by deleting the save method from the model class and Running all logic in my views.
@login_required
def create_investment_view(request):
if request.method == 'POST':
basic_investment_form = BasicInvestmentForm(request.POST)
if basic_investment_form.is_valid():
investment = basic_investment_form.save()
investment.basic_interest = investment.basic_deposit_amount * 365 * 0.02/2
investment.basic_investment_return = investment.basic_deposit_amount investment.basic_interest
investment.basic_investment_return = investment.basic_deposit_amount
investment.is_active = True
investment.save()
print(investment.basic_interest)
print(investment.basic_investment_return)
print(investment.basic_deposit_amount)
messages.success(request, 'your basic investment of {} is successfull '.format(investment.basic_deposit_amount))
else:
messages.success(request, 'your investment is not successfull! Try again.')
else:
basic_investment_form = BasicInvestmentForm()
context = {'basic_investment_form': basic_investment_form}
return render(request, 'create-basic-investment.html', context)
@login_required
def create_withdrawal_view(request):
if request.method == 'POST':
basic_withdraw_form = BasicWithdrawalForm(request.POST)
if basic_withdraw_form.is_valid():
investment = basic_withdraw_form.save(commit=False)
investment.basic_investment_return -= investment.basic_withdraw_amount
print(investment.basic_investment_return)
investment.save()
messages.success(request, 'your withdrawal of {} is successfull '.format(investment.basic_withdraw_amount))
else:
messages.success(request, 'your withdrawal of {} is unsuccessfull '.format(investment.basic_withdraw_amount))
else:
basic_withdraw_form = BasicWithdrawalForm()
context = {'basic_withdraw_form': basic_withdraw_form}
return render(request, 'create-basic-withdrawal.html', context)