You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django表单提交后表格数据不显示问题求助

Django股票交易记录应用表单提交后条目不显示问题修复

问题描述

我开发了一款股票交易记录简易应用,在Entry模型中实现了基于仓位、开盘价和收盘价计算盈亏(pnl)的功能。代码能正常执行并将正确的pnl值保存到数据库,但表单提交后,新条目无法在entries.html的表格中显示——只有点击浏览器返回按钮才会出现,手动刷新页面也无效,甚至所有条目都仅在点击返回后才显示。我尝试注释掉给pnl值上色的main.js代码,问题仍未解决。

相关代码

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")
    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)
    if form.is_valid():
      form.instance.trader = request.user
      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)
    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}"

main.js

document.addEventListener('DOMContentLoaded', function() {
    let displayObj = document.querySelectorAll('.entry_pnl');
    
    displayObj.forEach(function(el) {
        let pnlValue = parseFloat(el.innerText);
        
        if(pnlValue < 0) {
            el.style.color = 'red';
        } else {
            el.style.color = 'green';
        }
    });
});

问题分析

核心问题在EntryView的post方法中:

  1. 表单验证通过保存后,直接调用render返回页面,但没有传递entries数据,模板中的{% for entry in entries %}因无数据不渲染表格内容
  2. 直接返回渲染页面会让浏览器保留POST请求状态,刷新时会触发重复提交提示,且无法获取最新的条目列表

修复方案

1. 修改post方法,表单有效时重定向到GET请求

替换原post方法中表单有效时的返回逻辑,用redirect触发当前视图的GET请求,重新获取最新条目:

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()
        print('***************')
        print(f"Entry pnl:{form.instance.pnl}")
        # 重定向到当前路径,触发GET请求加载最新数据
        return redirect(request.path)
    else:
        messages.error(request, "Please correct the errors below.")
        # 表单无效时也要传递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})

2. 可选优化:自动计算pnl

将calculate_pnl整合到模型的save方法中,无需手动调用:

def save(self, *args, **kwargs):
    if self.position and self.open_price and self.close_price:
        self.pnl = round(self.position * self.close_price - self.position * self.open_price, 2)
    super().save(*args, **kwargs)

这样调用form.save()时会自动计算pnl,可删除form.instance.calculate_pnl()这行代码。

内容的提问来源于stack exchange,提问作者Andre Di Carlo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:34:50