Значения таблицы не отображаются после отправки формы с помощью Django
Я создал простое приложение для отслеживания сделок с акциями. У меня есть значение для каждой сделки "вход" под названием pnl, которое рассчитывает прибыль или убыток на основе размера позиции, цены открытия и цены закрытия. Все эти функции выполняются в модели Entry.
Я убедился, что код действительно выполняется правильно и сохраняет правильное значение в поле "Pnl" в базе данных. Но по какой-то причине новая запись, добавленная в таблицу (entries.html), отображается только при нажатии стрелки "назад" в браузере. Даже ручное обновление страницы ничего не дает.
Фактически, ни одна из записей не отображается, пока я не нажму кнопку "Назад".
entries.html:
{% extends 'base.html' %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% block title %}
Trading Journal
{% endblock title %}Trading Journal
{% block content %}
<form method="POST" enctype="multipart/form-data" action="/">
{% csrf_token %}
{{ form }}
<button>Submit</button>
</form>
{% endblock content %}
{% block table %}
<table class="blueTable sortable">
<thead>
<tr>
<th>Date</th>
<th>Ticker</th>
<th>Strategy</th>
<th>Result</th>
<th>Open Price</th>
<th>Position</th>
<th>Closed Price</th>
<th>P&L</th>
<th>Comments</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="9">
<div class="links"><a href="#">«</a> <a class="active" href="#">1</a> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a> <a href="#">»</a></div>
</td>
</tr>
</tfoot>
<tbody>
{% for entry in entries %}
<tr>
<td><a href="{% url 'single-entry' entry.id %}">{{entry.entered_date}}</a></td><td>{{entry.ticker}}</td><td>{{entry.strategy}}</td><td>{{entry.result}}</td><td>{{entry.open_price}}</td><td>{{entry.position}}</td><td>{{entry.close_price}}</td><td class="entry_pnl">{{entry.pnl}}</td><td>{{entry.comments}}</td></tr>
{% endfor %}
</tbody>
</tr>
</table>
{% if request.user.is_authenticated %}
<a href="{% url 'logout' %}"><button>Logout</button></a>
{% endif %}
{% endblock table %}
Views.py: (здесь отображается таблица со всеми записями, а также форма для ввода новой записи)
class EntryView(LoginRequiredMixin, View):
login_url = 'login'
def get(self, request):
logged_in_user = request.user.id
print("****************")
print(f'Logged in user:{logged_in_user}')
entries = Entry.objects.filter(trader_id=logged_in_user).order_by("entered_date") #see: https://docs.djangoproject.com/en/5.0/topics/db/queries/#field-lookups
form = EntryForm()
return render(request, "entries.html", {"form":form, "entries":entries, "user":logged_in_user})
def post(self, request):
form = EntryForm(request.POST, request.FILES) #must add request.FILES for uploads
if form.is_valid():
form.instance.trader = request.user #youre assigning one object to another; cant assign one object to a number. Or you could do trader_id on the LH side
form.instance.calculate_pnl()
form.save()
print('***************')
print(f"Entry pnl:{form.instance.pnl}")
return render(request, "entries.html")
else:
messages.error(request, "Please correct the errors below.")
return render(request, "entries.html", {"form":form})
Models.py:
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.urls import reverse
from django.contrib.auth.models import User
class Entry(models.Model):
ONEORB="1-Min ORB"
FIVEORB="5-Min ORB"
ABCD="ABCD"
REVERSAL="Reversal"
PROFIT="Profit"
LOSS="Loss"
RESULT_CHOICES = (
(PROFIT, "Profit"),
(LOSS, "Loss")
)
STRATEGY_CHOICES = (
(ONEORB,"1-Min ORB"),
(FIVEORB,"5-Min ORB"),
(ABCD,"ABCD"),
(REVERSAL,"Reversal")
)
entered_date=models.DateField(auto_now_add=True)
ticker=models.CharField(max_length=8, default="")
strategy=models.CharField(max_length=12, choices=STRATEGY_CHOICES, default="ONEORB")
result=models.CharField(max_length=6, choices=RESULT_CHOICES, default="PROFIT")
comments=models.TextField(max_length=300, blank=True)
image = models.ImageField(upload_to="", null=True, blank=True) #will save to default BASE_DIR which is 'uploads'
position = models.PositiveIntegerField(default=1, validators=[MinValueValidator(1)], blank=True, null=True)
open_price = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
close_price = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
pnl = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
trader = models.ForeignKey(User, on_delete=models.CASCADE, blank=False, related_name="entries")
def calculate_pnl(self):
self.pnl = round(self.position * self.close_price - self.position * self.open_price, 2)
def __str__(self):
return f"{self.result} {self.entered_date}"
Я попробовал закомментировать тег script, который указывает на мой следующий файл main.js, который кодирует значения цветом в зависимости от того, являются ли они положительными или отрицательными. Это не дало никакого эффекта.
main.js:
document.addEventListener('DOMContentLoaded', function() {
let displayObj = document.querySelectorAll('.entry_pnl');
displayObj.forEach(function(el) {
// Parse the inner text of the '.entry_pnl' element to get the numerical value
let pnlValue = parseFloat(el.innerText);
if(pnlValue < 0) {
el.style.color = 'red';
} else {
el.style.color = 'green';
}
});
});
вы отображаете шаблон "entries.html" без предоставления необходимого контекста для записей.
При отправке формы метод post сохраняет новую запись, но не включает обновленный список записей в контекст при повторной визуализации шаблона.
Обновите функцию post на эту:
def post(self, request):
form = EntryForm(request.POST, request.FILES)
if form.is_valid():
form.instance.trader = request.user
form.instance.calculate_pnl()
form.save()
messages.success(request, "Entry added successfully.")
else:
messages.error(request, "Please correct the errors below.")
# Retrieve the updated list of entries
logged_in_user = request.user.id
entries = Entry.objects.filter(trader_id=logged_in_user).order_by("entered_date")
return render(request, "entries.html", {"form": form, "entries": entries, "user": logged_in_user})