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

如何在Django中复用手动编写的创建表单更新文章

解决方案:复用手动表单实现新增/编辑功能

核心思路

把新增和编辑逻辑合并到同一个add_edit视图,通过可选的pk参数判断操作类型,直接复用现有add_edit.html模板,无需单独编写edit.html。


1. 修改urls.py,统一路由规则

替换原有新增、编辑的路由,让addEdit支持带pk(编辑)和不带pk(新增)两种请求:

# urls.py
path('add_edit/', views.add_edit, name='addEdit'),
path('add_edit/<int:pk>/', views.add_edit, name='addEdit'),
# 删除原来单独的edit路由:path('edit/<str:pk>/', views.edit, name='edit'),

如果你的主键是字符串类型,把<int:pk>改成<str:pk>即可。


2. 重构views.py的add_edit函数,兼容新增/编辑逻辑

调整函数接受可选pk参数,根据pk是否存在执行不同逻辑:

# views.py
from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Everything

@login_required(login_url='login')
def add_edit(request, pk=None):
    # 有pk则获取要编辑的对象,无pk则为新增
    post = get_object_or_404(Everything, pk=pk) if pk else None

    if request.method == 'POST':
        title = request.POST['title']
        name = request.POST['name']
        password = request.POST['password']
        details = request.POST.get('details', '')  # 非必填字段用get避免键不存在报错

        if title and name and password:
            if post:
                # 编辑模式:更新现有对象
                post.title = title
                post.name = name
                post.password = password
                post.details = details
                post.save()
            else:
                # 新增模式:创建新对象
                form_data = Everything(title=title, name=name, password=password, details=details)
                form_data.save()
            return redirect('home')
        else:
            messages.error(request, "请填写所有必填字段")
    
    # GET请求时,把post对象传递给模板(编辑时用于填充数据)
    context = {'post': post}
    return render(request, 'add_edit.html', context)

3. 修改add_edit.html模板,自动填充编辑数据

在表单控件中加入数据填充逻辑,区分新增/编辑状态:

<!-- add_edit.html -->
<form class="form text-center" action="{% if post %}{% url 'addEdit' pk=post.pk %}{% else %}{% url 'addEdit' %}{% endif %}" method="POST">
    {% csrf_token %}

    {% if messages %}
        {% for message in messages %}
            <p class="text-danger text-center fs-3 vov fade-in-up">{{ message }}</p>
        {% endfor %}
    {% endif %}

    <div class="mb-3 col-11 col-md-4 col-lg-3 mx-auto">
        <label for="title" class="form-label float-start" id="title_lable">TITLE</label>
        <input type="text" class="form-control" name="title" id="title" placeholder="U_U" value="{{ post.title|default:'' }}" required>
    </div>

    <div class="col-12"></div>

    <div class="mb-3 col-11 col-md-4 col-lg-3 mx-auto">
        <label for="name" class="form-label float-start" id="name_lable">NAME</label>
        <input type="text" class="form-control" name="name" id="name" placeholder="\((( ̄( ̄( ̄▽ ̄) ̄) ̄)))/" value="{{ post.name|default:'' }}" required>
    </div>

    <div class="col-12"></div>

    <div class="mb-3 col-11 col-md-4 col-lg-3 mx-auto">
        <label for="password" class="form-label float-start" id="password_lable">PASSWORD</label>
        <input type="password" class="form-control" name="password" id="password" placeholder="X_X" {% if post %}value="{{ post.password }}"{% endif %} required>
    </div>

    <div class="col-12"></div>

    <div class="mb-3 col-11 col-md-4 col-lg-3 mx-auto">
        <label for="details" id="details_lable" class="form-label">ANY THING ELSE</label>
        <textarea class="form-control" id="details" name="details" rows="3" placeholder="(_ _)。゜zzZ">{{ post.details|default:'' }}</textarea>
    </div>

    <input type="submit" id="btn_submit" class="btn col-11 col-md-4 col-lg-3" value="{% if post %}更新←{% else %}提交←{% endif %}">
</form>

关键修改点:

  • 表单action根据是否存在post对象,自动指向对应路由
  • 输入框用value="{{ post.field|default:'' }}"填充数据,default:''确保新增时不会显示None
  • 密码字段仅在编辑模式下填充现有值
  • 提交按钮文字随操作类型切换(可选,优化用户体验)

4. 修正home.html的编辑链接

把原来的编辑链接指向统一的addEdit路由:

<!-- home.html -->
<a href="{% url 'addEdit' pk=post.pk %}">
    <img width="48" height="48" src="https://img.icons8.com/fluency/48/pogchamp.png" alt="pogchamp"/>
</a>

如果之前出现Reverse for 'edit' with arguments '('',)' not found报错,检查home.html中遍历文章的循环是否正确(比如是否用了{% for post in posts %}),确保post变量存在且pk值有效。

内容的提问来源于stack exchange,提问作者unix nexo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:45:13