Reputation: 9
I am trying to update a model "Stock", then create a new "StockTransaction" at the same time. I want to accomplish this using two different forms submitted together. I am able to get the stock update transaction to work, but when I try to is_valid() on the transaction form, it always returns false. I can't figure out why it is returning false.
here are all of the relevant code sections that are used. Any help is appreciated. Thank you in advance!
def buyStock(request, pk):
stock = Stock.objects.get(id=pk)
form = StockForm(instance=stock)
tform = StockTransForm()
if request.method == 'POST':
form = StockForm(request.POST, instance=stock)
form.instance.buyPrice = stock.ticker.price
form.instance.dateOfPurchase = date.today()
form.instance.forSale = False
tform.instance.stockID = stock.stockID
tform.instance.buyPrice = stock.buyPrice
tform.instance.sellPrice = stock.ticker.price
tform.instance.broker = form.instance.broker
tform.instance.buyer = form.instance.ownerID
tform.instance.seller = stock.ownerID
tform.instance.ticker = stock.ticker
if form.is_valid() and tform.is_valid():
form.save()
tform.save()
class StockTransaction(models.Model):
transactionID = models.AutoField(primary_key=True)
ticker = models.ForeignKey(PublicCompany, on_delete=models.CASCADE, default=None,
related_name='stocktrans-ticker+')
stockID = models.IntegerField()
buyer = models.ForeignKey(FinancialAccount, on_delete=models.PROTECT, default=None,
related_name='stocktrans-buyer+')
seller = models.ForeignKey(FinancialAccount, on_delete=models.PROTECT, default=None,
related_name='stocktrans-seller+')
sellPrice = models.DecimalField(max_digits=7, decimal_places=2)
buyPrice = models.DecimalField(max_digits=7, decimal_places=2)
date = models.DateField(auto_now_add=True)
broker = models.ForeignKey(Agent, on_delete=models.PROTECT, default=None, related_name='stocktrans-broker+')
class Stock(models.Model):
ownerID = models.ForeignKey(FinancialAccount, on_delete=models.CASCADE, default=None,
related_name='stock-owner+')#on delete maybe change
buyPrice = models.DecimalField(max_digits=7, decimal_places=2)
broker = models.ForeignKey(Agent, on_delete=models.PROTECT, default=None, related_name='stock-broker+')
dateOfPurchase = models.DateField(auto_now_add=True)
ticker = models.ForeignKey(PublicCompany, on_delete=models.CASCADE, default=None)
stockID = models.IntegerField()
forSale = models.BooleanField(default=True)
class Meta:
unique_together = ['ticker', 'stockID']
class StockTransForm(ModelForm):
class Meta:
model = StockTransaction
fields = []
{% extends 'finances/base.html' %}
{% block content %}
<div class="content-section">
<form action="" method="POST">
{% csrf_token %}
{{form}}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Buy Asset</legend>
<h2>Are you sure you want to buy this asset - {{stock.ticker}}:{{stock.stockID}}</h2>
</fieldset>
<div class ="form-group">
<button class="btn btn-outline-danger" type ="submit">Buy</button>
<a class="btn btn-outline-secondary" href="{% url 'finance-forsale'%}">No</a>
</div>
</form>
</div>
{% endblock content %}
I have gone over every variable to make sure that they all match and are the same.
Upvotes: 0
Views: 37
Reputation: 8202
Don't know what's wrong, but updating instance is not the official way. What you should do is use commit=False to apply all data which came in through the form to obtain an instance which is not yet saved.
if request.method == 'POST':
form = StockForm(request.POST, instance=stock)
if form.is_valid():
f_instance = form.save( commit=False)
# now update instance with non-form data
f_instance.buyPrice = stock.ticker.price
f_instance.dateOfPurchase = date.today()
f_instance.forSale = False
# f_instance is not yet saved to the DB
#now similar code for tform to t_instance
...
# finally, save these instances to the DB
if form.is_valid() and tform.is_valid():
with transaction.atomic(): # unless the entire view is atomic
f_instance.save()
t_instance.save()
Upvotes: 1