在Django中输入后更新模型字段

时间:2020-10-19 20:01:09

标签: django

我正在尝试在用户从表单输入股票价格和数量之后更新帐户价值模型字段。本质上,用户将输入股票价格和股票数量,并且他们的帐户余额应反映购买量。以下是我的models.py,forms.py,views.py和buy_stock.html页面的图像。任何有关如何获取价值节省的见解将非常有帮助。提前致谢。 -总newb

Views.py

from django.shortcuts import render, redirect
from .models import Stock, Bank, BuyStockModel
from .forms import StockForm, BankForm, BuyStock, Registration
from django.contrib import messages
import requests 
import json
def main(request):
    stocks = BuyStockModel.objects.all().order_by('-created')
    form = BuyStock()
    account = Bank.objects.only('account')
    balance = account
    if request.method == 'POST': 
        price = request.POST.get('price')
        quantity = request.POST.get('quantity')
        if price is not None:
            price = float(price)
        if quantity is not None: 
            quantity = float(quantity)
            total = float(price) * float(quantity)
            if balance >= total:
                balance = balance - total
                account.update(account = balance)
        #account.save()
        ticker = request.POST['ticker']
        api_request = requests.get(
            "https://cloud.iexapis.com/stable/stock/" +
            ticker + 
            "/quote?token=i_should_get_a_new_one"
        )

        try:
            api = json.loads(api_request.content)
        except Exception as e:
            api = "Error..."
        context = {
            'api': api,
            'form' : form,
            'stocks' : stocks,
            "account" : account
        }
        return render(request, 'buy_stock.html', context)
    else:
        context = {'form' : form, 'stocks' : stocks}
        return render(request, 'buy_stock.html', context)

def buy_stock(request):
    print('buy_stock')
    if request.method == 'GET':
        form = BuyStock()
        stocks = BuyStockModel.objects.all().order_by('-created')
        output = {'form' : form, 'stocks' : stocks}
        return render(request, 'buy_stock.html', output)

    elif request.method == 'POST': 
        form = BuyStock(request.POST or None)
        if form.is_valid():
            form.save()
            name = form.cleaned_data['name']
            price = form.cleaned_data['price']
            quantity = form.cleaned_data['quantity'] 
            form = BuyStock()
            return redirect('buy_stock')
        return render(request, 'buy_stock.html', {
            'form' : form,
            'name' : name,
            'price' : price,
            'quantity' : quantity
        })

Models.py

from django.db import models 

class Stock(models.Model):
    ticker = models.CharField(max_length = 10)

    def __str__(self):
        return self.ticker

class Bank(models.Model):
    account = models.DecimalField(
        max_digits = 15, default = 30000.0, decimal_places = 0, 
        editable = True
    )

    def __str__(self):
        return self.account

class BuyStockModel(models.Model):
    name = models.CharField(max_length = 100)
    option = models.CharField(max_length = 10, default = 'buy')
    price = models.DecimalField(
        max_digits = 15, decimal_places = 2, default = 0
    )
    quantity = models.DecimalField(
        max_digits = 15, decimal_places = 0, default = 0
    )
    total_value = models.DecimalField(
        max_digits = 15, default = 1, decimal_places = 0,
        editable = True
    )
    created = models.DateTimeField(auto_now_add = True)

    def __str__(self):
        return self.price

    def __str__(self):
        return self.quantity

    def calc_total(self):
        amount = (self.price * self.quantity)
        return amount

    def save_total(self):
        self.total_value = self.calc_total()
        super(BuyStockModel, self).save()

Forms.py

from django import forms
from .models import Stock, Bank, BuyStockModel
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class Registration(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ["username", "email", "password1", "password2"]

class StockForm(forms.ModelForm):
    class Meta:
        model = Stock
        fields = ["ticker"]

class BankForm(forms.ModelForm):
    class Meta:
        model = Bank
        fields = ["account"]

class BuyStock(forms.ModelForm):
    class Meta:
        model = BuyStockModel
        fields = ["name", "price", "quantity"]

        widgets = {
            'name' : forms.TextInput(attrs = {'class' : 'form-control'}),
            'price' : forms.TextInput(attrs = {'class' : 'form-control'}),
            'quantity' : forms.TextInput(attrs = {'class' : 'form-control'}),
        }

buy_stock.html

{% extends 'base.html' %}
{% block content %}

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Project-4 Buy Stock page</title>  
    </head>
    <body>
        <div class="container"></div>
        <h1>Buy Stock</h1>
        <br/>
        <div>
            <form action = "{%url 'main' %}" class="form-inline my-2 my-lg-0" method = "POST">
                {% csrf_token %}
              <input class="form-control mr-sm-2" type="search" placeholder="Get Stock Quote" aria-label="Search" name = "ticker">
              <button class="btn btn-outline-secondary my-2 my-sm-0" type="submit">Stock Quote</button>
            </form>
        </div>
        <br/>
        <br/>
        <div>
            {% if ticker %}
                    {{ ticker }}
                {% endif %}
    
                {% if api %}
                    {% if api == "Error..." %}
                        There was a problem with your ticker symbol, 
                        please try again...
                    {% else %}
                        <h2>{{ api.companyName }}</h2>
                        <br/>
                        {% load humanize %}
                        Price: ${{ api.latestPrice|intcomma }}<br/>
                        Previous Close: ${{ api.previousClose|intcomma }}<br/>
                        Market Cap: ${{ api.marketCap|intcomma }}<br/>
                        YTD Change: {{ api.ytdChange }}<br/>
                        52 Week High: ${{ api.week52High|intcomma }}<br/>
                        52 Week Low: ${{ api.week52Low|intcomma }}<br/>
                        <br/>
        
                    {% endif %}
                
                {% else %}
        
                {% endif %}
        </div>
        <br/>
        <div>
            <h6 class = "bold">Total in Account</h6>
            {% for item in account %}
            {% load humanize %}
            <h1 class = "bold">${{ item.account|intcomma }}</h1>
            {% endfor %}
        </div>
        <div class="container">
            <div class="row">
              <div class="col-sm">
                <div class = "form-group">
                    <form action = "{%url 'buy_stock' %}" method = "POST">
                        {% csrf_token %}
                        {{ form.as_p }}
        
                        <div class="dropdown">
                            <div class="dropdown">
                                <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                  Trading Options
                                </button>
                                <div class="dropdown-menu" aria-labelledby="dropdownMenu2">
                                  <button class="dropdown-item" type="sumbit">Buy</button>
                                  <button class="dropdown-item" type="submit">Sell</button>
                            </div>
                          </div>
                    </form>
                </div>
              </div>
            <div class="row">
                <div class="col-sm">
                  <table class="table table-striped table-bordered table-hover">
                      <thead class="thead-dark">
                      <tr>
                          <th scope="col">Date Purchased</th>
                          <th scope="col">Company Name</th>
                          <th scope="col">Stock Price</th>
                          <th scope="col">Shares Purchased</th>
                      </tr>
                      </thead>
                      <tbody>
                              {% for item in stocks %}
                          <tr>
                                  {% load humanize %}
                                  <th scope="row">{{ item.created }}</th>
                                  <td>{{ item.name }}</td>
                                  <td>${{ item.price|intcomma }}</td>
                                  <td>{{ item.quantity|intcomma }} Shares</td>
                          </tr>
                              {% endfor %}
      
                      </tbody>
                  </table>
              <br/>
              {% for item in stocks %}
                  <a class="btn btn-danger" href = "{% url 'sell_stock' item.id %}">Delete {{ item.name }}</a> &nbsp;&nbsp;&nbsp;
              {% endfor %}
              </div>
              </div>
            </div>
            </div>
        </div>
        <br/>
        <br/>
        <br/>
         
    </body>

{% endblock %}

1 个答案:

答案 0 :(得分:0)

我认为您应该首先了解模型关系。您的数据模型将无法以这种方式工作并加以修复,希望其余的将变得更加清晰。

订单(您称为BuyStockModel)是产品与客户的婚姻。因此,此订单模型应具有与产品(库存)和客户(在您的情况下,由其银行帐户代表)的链接。经纪人有双向订单:销售订单和采购订单,但是对于基本数据模型来说并不重要。

我将在下面使用Order,因为BuyStockModel对我来说不是一个好名字:)。

所以您需要两个关系:

          Order
          /   \
       Stock  Bank

Django为此关系使用了ForeignKey

class Order(models.Model):
    stock = models.ForeignKey(Stock, on_delete=models.PROTECT)
    account = models.ForeignKey(Bank, on_delete=models.PROTECT)
    option = models.CharField(max_length = 10, default = 'buy')
    price = models.DecimalField(
        max_digits = 15, decimal_places = 2, default = 0
    )
    quantity = models.DecimalField(
        max_digits = 15, decimal_places = 0, default = 0
    )
    created = models.DateTimeField(auto_now_add = True)

    @property
    def total_value(self):
        return self.price * self.quantity

    def __str__(self):
        return (
           f"{self.option.upper()}: {self.id} / qt: {self.quantity}"
           f" / price: {self.price}"
        )

您现在可以使用Order模型构造单个“ OrderForm”,该模型可以呈现帐户和股票报价器。那应该可以让您如愿以偿。