Как обновить баланс счета пользователя при покупке в Django View?
В качестве побочного проекта я работаю над созданием симулированного приложения для обмена криптовалют. Для первой части я просто создаю простую страницу, где пользователи могут покупать и продавать BTC за USD, и она будет обновлять их соответствующие балансы для каждого из них. Я создал форму для 'Trade' и две таблицы модели - 'Trade' и 'Portfolio.
Как настроить это так, чтобы при совершении "сделки" обновлялось количество токенов (при покупке) или количество USD (при продаже) в "портфеле", а если их нет, то создавалась новая запись?
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']
Я искал в документации, но не смог найти никаких примеров.
В блоке if form.is_valid():
просто добавьте следующий блок после instance.save()
и настройте по необходимости.
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()
я бы написал функцию для этого (быстро и грязно, чтобы вы могли видеть, что делать):
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()
тогда просто вызовите функцию, указав request.user
в качестве пользователя и суммы