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

如何提交Django表单且不丢失已渲染的HTML内容?

问题:Django提交表单页面重载丢失数据,如何无重载调用视图?

我是Django框架新手,正在开发一个包含3个HTML表单的小项目。预期流程为:先在「Input String」字段提交文本,再提交该文本的子串来增加分数。但提交子串时页面会重载,重置已渲染的HTML,导致丢失原输入的主字符串。点击「Submit Stuart」提交子串表单时,页面跳转到http://127.0.0.1:8000/someapp/consonant_submit,丢失原页面http://127.0.0.1:8000/someapp的HTML数据,想知道如何调用Django视图函数且不触发页面重载。

现有代码

HTML表单代码

<div style="padding: 20px;">
    <h1>Words Starting with consonants</h1>
    <form id="form2" action="consonant_submit/" method="post">
        {% csrf_token %}
        <label for="Stuart">Stuart Text:</label>
        <input type="text" id="stuart" name="stuart">
        <br>
        <label for="2">Stuart Score:</label>
        <input type="text" id="score1" name="score1">
        <br>
        <input type="submit" value="Submit stuart">
    </form>
</div>

<div style="padding: 20px;">
    <h1>Words Starting with consonants</h1>
    <form id="form3" action="vowel_submit/" method="post">
        {% csrf_token %}
        <label for="kevin">Kevin Text:</label>
        <input type="text" id="kevin" name="kevin">
        <br>
        <label for="2">Kevin Score:</label>
        <input type="text" id="score2" name="score2">
        <br>
        <input type="submit" value="Submit kevin">
    </form>
</div>

urls.py代码

from django.urls import path
from . import views

urlpatterns = [
    path("",views.index,name="index"),
    path('consonant_submit/', views.consonant_submit, name='consonant_submit'),
    path('vowel_submit/', views.vowel_submit, name='vowel_submit'),
]

views.py代码

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
    res = render(request,'minion_game.html')
    return res

def consonant_submit(request):
    if request.method == 'POST':
        input1 = request.POST.get('stuart')
        # Process the stuart data as needed

        res = render(request,'minion_game.html')
        return res
    else:
        return HttpResponse('Invalid request method')

def vowel_submit(request):
    if request.method == 'POST':
        input2 = request.POST.get('kevin')
        # Process the kevin data as needed
        res = render(request,'minion_game.html')
        return res
    else:
        return HttpResponse('Invalid request method')

解决方案:用AJAX异步提交表单

核心是通过JavaScript的Fetch API异步发送表单数据,不触发页面跳转,同时保留页面原有内容。

1. 修改视图函数返回JSON响应

原来的视图提交后重新渲染页面,现在改为返回处理后的结果(比如计算后的分数),用JSON格式传递数据:

from django.shortcuts import render
from django.http import JsonResponse

def index(request):
    return render(request,'minion_game.html')

def consonant_submit(request):
    if request.method == 'POST':
        input1 = request.POST.get('stuart')
        # 这里替换成你的实际分数计算逻辑
        score = len(input1)  # 示例:按子串长度算分
        return JsonResponse({'status': 'success', 'score': score})
    else:
        return JsonResponse({'status': 'error', 'message': '无效请求方法'}, status=400)

def vowel_submit(request):
    if request.method == 'POST':
        input2 = request.POST.get('kevin')
        score = len(input2)  # 示例计算逻辑
        return JsonResponse({'status': 'success', 'score': score})
    else:
        return JsonResponse({'status': 'error', 'message': '无效请求方法'}, status=400)

2. 修改HTML表单,添加JS异步提交逻辑

给表单添加提交事件监听,阻止默认跳转行为,用Fetch发送请求并更新页面内容:

<div style="padding: 20px;">
    <h1>Words Starting with consonants</h1>
    <form id="form2" action="consonant_submit/" method="post">
        {% csrf_token %}
        <label for="Stuart">Stuart Text:</label>
        <input type="text" id="stuart" name="stuart">
        <br>
        <label for="score1">Stuart Score:</label>
        <input type="text" id="score1" name="score1" readonly>
        <br>
        <input type="submit" value="Submit stuart">
    </form>
</div>

<div style="padding: 20px;">
    <h1>Words Starting with vowels</h1>
    <form id="form3" action="vowel_submit/" method="post">
        {% csrf_token %}
        <label for="kevin">Kevin Text:</label>
        <input type="text" id="kevin" name="kevin">
        <br>
        <label for="score2">Kevin Score:</label>
        <input type="text" id="score2" name="score2" readonly>
        <br>
        <input type="submit" value="Submit kevin">
    </form>
</div>

<script>
// 获取Django的CSRF令牌,POST请求必须验证
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;

// 处理Stuart表单提交
document.getElementById('form2').addEventListener('submit', function(e) {
    e.preventDefault(); // 阻止默认页面跳转
    const formData = new FormData(this);
    
    fetch(this.action, {
        method: 'POST',
        headers: {
            'X-CSRFToken': csrftoken,
        },
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        if (data.status === 'success') {
            // 更新页面上的分数显示
            document.getElementById('score1').value = data.score;
        } else {
            alert(data.message);
        }
    })
    .catch(() => alert('提交失败,请重试'));
});

// 处理Kevin表单提交
document.getElementById('form3').addEventListener('submit', function(e) {
    e.preventDefault();
    const formData = new FormData(this);
    
    fetch(this.action, {
        method: 'POST',
        headers: {
            'X-CSRFToken': csrftoken,
        },
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        if (data.status === 'success') {
            document.getElementById('score2').value = data.score;
        } else {
            alert(data.message);
        }
    })
    .catch(() => alert('提交失败,请重试'));
});
</script>

3. 保留主字符串的小技巧

如果需要持久化用户输入的主字符串,可以用以下两种方式:

  • 隐藏输入框:主字符串提交后,把值存入页面的隐藏输入框,后续提交子串时可以一起传递:
    <input type="hidden" id="main_string" name="main_string" value="{{ main_string }}">
    
  • localStorage存储:用JavaScript把主字符串存在浏览器本地存储,需要时取出:
    // 主字符串提交时保存
    localStorage.setItem('mainString', document.getElementById('main_input').value);
    // 后续需要时读取
    const mainStr = localStorage.getItem('mainString');
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 18:40:46