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

Django UpdateView无法更新数据及消息/打印无输出问题求助

Django股票交易日志应用问题排查

我开发了一款用于股票交易记录的Django应用,作为journaling工具。用户从首页点击单条日志条目后,会进入由UpdateView处理的详情页(single_entry.html),可编辑更新条目信息或删除该条目,表单设有“保存”(对应update_button)和“删除”按钮。

目前存在两个问题:

  • 删除功能正常,但更新功能原本可用现在失效,条目信息无任何变化;
  • messages中间件的消息无法显示在页面,print()语句也无控制台输出。

代码文件

views.py

from django.forms.models import BaseModelForm
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.views import View
from django.contrib import messages
from django.urls import reverse_lazy
from .forms import EntryForm
from .models import Entry
from django.views.generic.edit import UpdateView, DeletionMixin
from django.views.generic import DeleteView


# Create your views here. 

class EntryView(View):
  def get(self, request):
    entries = Entry.objects.all().order_by("entered_date")
    form = EntryForm()
    return render(request, "entries.html", {"form":form, "entries":entries})
  
  def post(self, request):
    form = EntryForm(request.POST, request.FILES) #must add request.FILES for uploads
    print(request.FILES)
    if form.is_valid():
      form.save()
      messages.success(request, "Entry created!")
      return redirect("/")
    else:
      messages.error(request, "Please correct the errors below.")
      return render(request, "entries.html", {"form":form})

class SingleEntryView(UpdateView):
  template_name = "single_entry.html"
  model = Entry
  fields = ['ticker', 'strategy', 'result', 'comments', 'image']
  success_url = '/'
  form = EntryForm

  def post(self, request, *args, **kwargs):
        if 'delete_button' in self.request.POST:
            self.object = self.get_object()
            self.object.delete()
            messages.success(request, "Entry has been deleted")
            return HttpResponseRedirect(self.get_success_url())
        elif 'update_button' in self.request.POST:  
            return super().post(request, *args, **kwargs)
        return redirect('/')

  def form_valid(self, form):
    form.instance.user = self.request.user
    return super().form_valid(form)

urls.py

from django.urls import path
from django.contrib import admin
from . import views

urlpatterns = [
    path("", views.EntryView.as_view(), name="index"),
    path("entries/<int:pk>/", views.SingleEntryView.as_view(), name="single-entry"),
    path("admin/", admin.site.urls)
]

single_entry.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 - Entry
{% endblock title %}Trading Journal

{% block content %}

<form method="POST" action="">
    {% csrf_token %}
    {% for field in form %}
        {{field.label_tag}}
        {{field}}
        {% if field.errors %}
            <small class="error">{{ field.errors|striptags }}</small>            
        {% endif %}
    {% endfor %}
    <button type="submit" name="update_button">Save</button>
    <button tyupe="submit" name="delete_button">Delete</button>

</form>    

<!-- {% if entry.image.url != Null %} -->
    <img src="{{ entry.image.url }}" alt="{{ entry.result }}">
        <!-- {% else %} -->
    <img src="" alt="{{ entry.result }}">
<!-- {% endif %} -->

{% endblock content %}

models.py

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.urls import reverse
from django.utils.text import slugify


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'

    def __str__(self):
        return f"{self.result} {self.entered_date}"

forms.py

from django import forms
from .models import Entry

class EntryForm(forms.ModelForm):
    class Meta:
        model=Entry
        fields='__all__'

问题修复方案

1. 更新功能失效修复

你的SingleEntryView同时设置了fields和form属性,导致Django优先使用fields自动生成表单,忽略了自定义的EntryForm;另外表单未处理文件上传,缺少request.FILES传递。

修改SingleEntryView:

class SingleEntryView(UpdateView):
  template_name = "single_entry.html"
  model = Entry
  form_class = EntryForm  # 替换原form属性为form_class
  success_url = '/'

  def post(self, request, *args, **kwargs):
        if 'delete_button' in request.POST:
            self.object = self.get_object()
            self.object.delete()
            messages.success(request, "Entry has been deleted")
            return HttpResponseRedirect(self.get_success_url())
        elif 'update_button' in request.POST:  
            self.object = self.get_object()
            # 手动传递request.FILES处理图片上传
            form = self.get_form_class()(request.POST, request.FILES, instance=self.object)
            if form.is_valid():
                return self.form_valid(form)
            else:
                return self.form_invalid(form)
        return redirect('/')

  def form_valid(self, form):
    # 注意:你的Entry模型没有user字段,需删除此行或给模型添加user字段
    # form.instance.user = self.request.user
    messages.success(self.request, "Entry updated successfully!")
    return super().form_valid(form)

同时修改模板表单,添加文件上传必需的属性:

<form method="POST" action="" enctype="multipart/form-data">

2. Messages不显示修复

  • 确保settings.py启用了消息中间件:
MIDDLEWARE = [
    # 其他中间件...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # 其他中间件...
]
  • 确保settings.py配置了消息存储后端:
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
  • 将模板中的消息代码块移到{% block content %}内部(base.html可能未预留外部位置):
{% block content %}
{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

<!-- 表单代码 -->
{% endblock %}

3. Print语句无输出修复

print语句的输出会出现在Django开发服务器的终端窗口中,而非浏览器控制台,查看启动runserver的那个终端即可。


内容的提问来源于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.28 13:44:56