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

Django UpdateView提交表单未更新对象反而创建新实例问题

Django 更新表单提交后生成新文章而非修改原文章

GET请求能正确预填已有文章内容到更新表单,但提交表单后原文章未被更新,反而生成了一个带新uid的新文章,原文章仍保留原uid。

已验证内容

  • 更新视图通过instance参数用已有实例初始化ModelForm
  • URL配置包含主键(uid)

简化后的代码

views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Article
from .forms import ArticleForm

def ArticleUpdate(request, pk):
    # Fetch the existing article using the uid passed via URL
    article = get_object_or_404(Article, uid=pk)
    
    if request.method == 'POST':
        # IMPORTANT: The form is instantiated with the existing instance!
        form = ArticleForm(request.POST, request.FILES, instance=article)
        if form.is_valid():
            form.save()  # Expect this to update, not create a new article
            return redirect('article-read', pk=article.uid)
        else:
            print("Form errors:", form.errors)
    else:
        form = ArticleForm(instance=article)
    
    context = {'form': form}
    return render(request, 'blog/article_form.html', context)

urls.py

from django.urls import path
from blog import views

urlpatterns = [
    path('articles/create/', views.ArticleCreate, name='article-create'),
    path('articles/<str:pk>/', views.ArticleRead, name='article-read'),
    path('articles/<str:pk>/update/', views.ArticleUpdate, name='article-update'),
]

模板 (article_form.html)

{% extends 'base.html' %}

{% block content %}
  <h2>{% if form.instance.pk %}Update{% else %}Create{% endif %} Article</h2>
  <form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">{% if form.instance.pk %}Update{% else %}Create{% endif %}</button>
  </form>
{% endblock %}

Article 模型 (models.py)

class Article(models.Model):
    # author =
    # category =
    uid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

ArticleForm (forms.py)

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = '__all__'

已再次检查

  • 表单提交到正确的URL(带文章pk的更新URL)
  • 视图在POST请求时始终传递已有实例给表单
  • 没有重复的URL模式导致POST请求误路由到创建视图

尽管如此,提交表单仍会创建新文章而非更新原文章。

已尝试操作

  • 验证浏览器URL包含正确的pk
  • 在视图中添加打印语句确认加载了正确的实例
  • 确认表单字段正确,模型主键(UUID字段)不可编辑

是否有人遇到过这种情况?会不会是模板问题(比如硬编码action属性导致POST请求命中错误视图),或者还有其他我遗漏的点?

任何指导都将不胜感激。

环境:

  • Django 5.2
  • Python 3.12
  • Article模型使用UUIDField作为主键(不可编辑)

内容的提问来源于stack exchange,提问作者Ojas Mutreja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:50:08