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()