Django中编辑与预览视图跳转时保留表单已填内容的实现问题
解决方案
你原来的实现存在两个核心问题:一是预览页的返回表单没有携带用户输入的title、body数据,提交回编辑页时只有return字段,视图拿不到之前的输入内容;二是直接在preview视图里调用new_entry视图函数的做法不符合Django常规设计,容易出现请求上下文传递异常。按照下面两步修改即可解决问题:
1. 修改预览页HTML,添加隐藏字段携带表单数据
在预览页的返回表单中新增两个隐藏输入框,把当前预览的标题和正文内容携带到提交请求中:
{% extends "encyclopedia/layout.html" %} {% block title %} Encyclopedia {% endblock %} {% block body %} <h1>Preview</h1> <h3>{{title}}</h3> <hr> {{preview|safe}} <form action="{% url 'new_entry' %}" method="POST"> {% csrf_token %} <!-- 新增两个隐藏字段,传递当前预览的表单数据 --> <input type="hidden" name="title" value="{{ title }}"> <input type="hidden" name="body" value="{{ preview }}"> <input type="submit" name="return" value="Return"> </form> {% endblock %}
2. 调整视图逻辑,统一在new_entry视图处理所有请求
你可以直接把预览逻辑合并到new_entry视图中,不需要单独维护preview视图,避免跨视图传参的麻烦,修改后的视图代码如下:
def new_entry(request): # POST请求用提交的数据初始化表单,GET请求初始化空表单 form = EntryForm(request.POST or None) if request.method == 'POST': # 表单校验通过后处理对应操作 if form.is_valid(): title = form.cleaned_data['title'] body = form.cleaned_data['body'] # 点击保存按钮:存储markdown文件 if 'submit' in request.POST: util.save_entry(title, body) return redirect(reverse('new_entry')) # 点击预览按钮:渲染预览页 elif 'preview' in request.POST: return render(request, "encyclopedia/entry_preview.html", {"title": title, "preview": body}) # 点击返回按钮:直接渲染编辑页,表单会自动填充已输入内容 if 'return' in request.POST: return render(request, 'encyclopedia/new_entry.html', {'form': form}) # 普通GET请求渲染空编辑页 return render(request, 'encyclopedia/new_entry.html', {'form': form})
原理说明:Django的表单实例如果用传入的POST数据初始化,渲染到模板时会自动填充对应字段的内容,预览页的返回操作把用户之前输入的全部内容作为隐藏字段提交回编辑页,刚好可以用来初始化表单,不需要额外处理就能保留所有输入内容。Django模板渲染隐藏字段的value时会自动转义特殊字符,不会出现XSS安全问题。
内容的提问来源于stack exchange,提问作者crispo12
相关产品推荐
相关产品推荐

