Django自定义HTML表单实现Todo模型的数据保存与更新
自定义Todo表单的持久化存储实现
表单前置修正
- 给表单添加文件上传必需的属性:原有
<form>标签需补充enctype="multipart/form-data",否则Django无法接收上传的图片文件,修改后标签为<form method="POST" enctype="multipart/form-data" action=""> - 修正文件上传控件:当前
<input type="file" name="image" multiple />的multiple属性需删除,因为模型中的image是单图字段,保留多图属性会导致后端接收多文件时赋值报错 - 移除无实际作用的属性:文件输入框上的
@change="fileName"是Vue指令语法,纯Django模板场景下无效果,可删除,如需展示本地选中文件名的逻辑自行编写原生JS即可
视图层持久化逻辑
在views.py中新增新增待办的处理函数,直接从请求中提取字段值写入模型,无需依赖Django表单类渲染:
from django.shortcuts import render, redirect from .models import Todo def add_todo(request): if request.method == "POST": # 提取POST请求中的普通字段 title = request.POST.get("title", "").strip() description = request.POST.get("description", "") priority = request.POST.get("priority", "Low") # 处理复选框逻辑:勾选时POST中存在键值为on,未勾选时无对应键,默认设为False on_hold = request.POST.get("on_hold") == "on" # 提取FILES中的上传图片 image = request.FILES.get("image") # 基础校验,可自行扩展规则 if not title: return render(request, "add-post.html", {"error": "待办标题不能为空"}) # 直接创建模型实例并写入数据库 Todo.objects.create( title=title, description=description, priority=priority, on_hold=on_hold, image=image ) # 保存完成后跳转至待办列表页或详情页 return redirect("todo_list") return render(request, "add-post.html")
路由绑定
在应用的urls.py中配置路径,将表单提交和上述视图绑定即可,例如:
from django.urls import path from .views import add_todo, update_todo urlpatterns = [ path("add/", add_todo, name="add_todo"), # 后续更新接口的路径 path("update/<int:todo_id>/", update_todo, name="update_todo"), ]
自定义更新表单的同步修改实现
模板回填逻辑
进入更新页时,需先从数据库取出对应待办的存量数据,回填到表单中,避免用户重复录入全部内容,参考更新页表单代码:
<form method="POST" enctype="multipart/form-data" action=""> {% csrf_token %} <input name="title" type="text" value="{{ todo_item.title }}"> <textarea spellcheck="false" name="description">{{ todo_item.description }}</textarea> <input type="file" name="image" /> <select required name="priority"> <option value="Low" {% if todo_item.priority == 'Low' %}selected{% endif %}>Low</option> <option value="Medium" {% if todo_item.priority == 'Medium' %}selected{% endif %}>Medium</option> <option value="High" {% if todo_item.priority == 'High' %}selected{% endif %}>High</option> </select> <input type="checkbox" name="on_hold" {% if todo_item.on_hold %}checked{% endif %}> <button type="submit">Update ToDo</button> </form>
更新视图逻辑
更新逻辑和新增逻辑的核心差异是:需先定位到要修改的存量对象,仅覆盖用户提交的字段,未重新上传图片时保留原有图片资源:
from django.shortcuts import render, get_object_or_404, redirect from .models import Todo def update_todo(request, todo_id): # 定位待修改的Todo对象,不存在则返回404 todo_item = get_object_or_404(Todo, id=todo_id) if request.method == "POST": title = request.POST.get("title", "").strip() description = request.POST.get("description", "") priority = request.POST.get("priority", "Low") on_hold = request.POST.get("on_hold") == "on" new_image = request.FILES.get("image") if not title: return render(request, "update-todo.html", { "todo_item": todo_item, "error": "待办标题不能为空" }) # 覆盖更新各字段 todo_item.title = title todo_item.description = description todo_item.priority = priority todo_item.on_hold = on_hold # 仅当用户上传新图片时才替换旧图,未上传则保留原有资源 if new_image: todo_item.image = new_image # 触发模型更新 todo_item.save() return redirect("todo_list") # 非POST请求时,将存量数据传给模板做回填 return render(request, "update-todo.html", {"todo_item": todo_item})
常见踩坑提示
- 确保
settings.py中已配置MEDIA_ROOT和MEDIA_URL,否则上传的图片无法正常存储和访问 - 富文本字段
RichTextField的内容包含HTML标签,前端渲染时需加|safe过滤器,否则会原样显示标签源码 - 模型字段的choices选项和前端select的value值要完全对应,否则会触发Django的字段校验报错
内容的提问来源于stack exchange,提问作者Mubasher Rehman
相关产品推荐
相关产品推荐

