Значения таблицы не отображаются после отправки формы с помощью 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="#">&laquo;</a> <a class="active" href="#">1</a> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a> <a href="#">&raquo;</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})
Вернуться на верх