Home > Software design >  How to update a users account balance on purchase in a Django View?
How to update a users account balance on purchase in a Django View?

Time:07-09

For a side project I'm working on creating a simulated cryptocurrency exchange application. For the first part of this I'm just creating a simple page where the users can buy and sell BTC for USD and it will update their respective balances for each one. I have created a form for the 'Trade' and there's two model tables - 'Trade' and 'Portfolio.

How do I set this up so when a 'Trade' takes place, it updates the amount of tokens (when buying) or the amount of USD (when selling) in the 'Portfolio', and if it doesn't exist it creates a new entry?

models.py:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Trade(models.Model):
    token_name = models.CharField(max_length=100)
    token_symbol = models.CharField(max_length=10)
    date = models.DateTimeField(default=timezone.now)
    account = models.ForeignKey(User, on_delete=models.CASCADE, related_name='trader')
    amount = models.FloatField()
    price = models.FloatField()
    type = models.CharField(max_length=15,
                              choices=(
                                  ("Market Buy", "Market Buy"),
                                  ("Market Sell", "Market Sell")))

    def id(self):
        return id(self.id)

class Portfolio(models.Model):
    token_name = models.CharField(max_length=100, unique=True, default="United States Dollar")
    token_symbol = models.CharField(max_length=10, default="USD")
    account = models.ForeignKey(User, on_delete=models.CASCADE, related_name='portfolio')
    amount_holding = models.FloatField(default="100000")

    def id(self):
        return id(self.id)

Views.py:

from django.shortcuts import render
from django.http import HttpResponse
from .models import Trade
from .models import Portfolio
from django.contrib import messages
from .filters import TradeFilter
from .forms import BuyForm
from .forms import SellForm
from django.http import HttpResponseRedirect
import datetime

def home(request):
    data = ''
    trades = Trade.objects.filter(account=request.user.id)
    myFilter = TradeFilter(request.GET, queryset=trades)
    trades = myFilter.qs
    buyform = BuyForm()
    sellform = SellForm()
    context = {
        'trades': trades,
        'myFilter':myFilter,
        'buyform': buyform,
        'sellform': sellform
    }
    if request.method == 'GET':
        if request.user.is_authenticated == False:
            messages.info(request, 'You need to register and log in to use these features')
    if request.method == 'POST':
        if request.POST.get("form_type") == 'BuyForm':
            if request.user.is_authenticated:
                buyform = BuyForm(request.POST)
                if buyform.is_valid():
                    instance = buyform.save(commit=False)
                    instance.account = request.user
                    instance.token_name = 'Bitcoin'
                    instance.token_symbol = 'BTC'
                    remove_funds = 30000 * instance.amount
                    instance.price = -abs(remove_funds)
                    instance.type = 'Market Buy'
                    instance.save()
                    return HttpResponseRedirect(request.path_info)

            else:
                messages.error(request, 'Buy error: You are not logged in')
        elif request.POST.get("form_type") == 'SellForm':
            if request.user.is_authenticated:
                sellform = SellForm(request.POST)
                if sellform.is_valid():
                    instance = sellform.save(commit=False)
                    instance.account = request.user
                    instance.token_name = 'Bitcoin'
                    instance.token_symbol = 'BTC'
                    instance.price = 30000 * instance.amount
                    instance.type = 'Market Sell'
                    instance.save()
                    return HttpResponseRedirect(request.path_info)
            else:
                messages.warning(request, 'Sell error: You are not logged in')
    return render(request, 'exchange/home.html', context)

EDIT: forms.py:

from django import forms
from django.forms import ModelForm
from .models import Trade
from .models import Portfolio

class BuyForm(ModelForm):
    class Meta:
        model = Trade
        fields = ['amount']

class SellForm(ModelForm):
    class Meta:
        model = Trade
        fields = ['amount']

I've been searching in the documentation but I haven't been able to find any examples.

CodePudding user response:

i would write a function for this (quick and dirty so you can see what to do):

def update_portfolios(user, btc_amount, usd_amount):
    btc_portfolio, _ = Portfolio.objects.get_or_create(account=user, token_symbol='BTC', token_name='Bitcoin')
    usd_portfolio, _ = Portfolio.objects.get_or_create(account=user, token_symbol='USD', token_name='United States Dollar')
    btc_portfolio.amount_holding = btc_amount
    usd_portfolio.amount_holding = usd_amount
    btc_portfolio.save()
    usd_portfolio.save()

then just call the function with request.user as user and the amounts

CodePudding user response:

In the if form.is_valid(): block just add the following block after instance.save() and adjust as needed.

portfolio, __ = Portfolio.objects.get_or_create(
    account=instance.account,
    token_name=instance.token_name
    token_symbol=instance.token_symbol
)
portfolio.amount = portfolio.amount   token_symbol // or - for the other form
portfolio.save()
  • Related