如何在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
相关产品推荐
相关产品推荐

