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

Django:如何用原生JS的Fetch替代Ajax实现按钮点击不刷新页面?

解决方案:无刷新提交表单并更新内容

步骤1:重构Django视图与表单,统一管理选项

首先修改views.py,拆分出专门处理AJAX请求的视图,同时从forms.py的SimpleCombobox类中读取选项,避免硬编码,方便后续扩展:

修改后的views.py

from django.http import JsonResponse
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .forms import SimpleCombobox

@login_required
def home(request):
    # 从表单类中获取颜色选项,统一管理
    color_choices = [choice[0] for choice in SimpleCombobox.COLOR_CHOICES]
    context = {'color_choices': color_choices}
    return render(request, 'app1/home.html', context)

@login_required
def get_color_message(request):
    if request.method == "POST" and request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        picked = request.POST.get('color')
        message = ''
        if picked == 'Red':
            message = "<<< You chose red"
        elif picked == 'Blue':
            message = "<<< You chose blue"
        elif picked == 'Black':
            message = "<<< You chose black"
        else:
            message = "<<< Oh no, you chose orange"
        return JsonResponse({'message': message})
    return JsonResponse({'error': 'Invalid request'}, status=400)

沿用并扩展forms.py(统一管理选项)

已有的SimpleCombobox类可直接使用,后续新增下拉框选项时,只需在此文件添加新表单类即可,无需修改JS或视图核心逻辑:

from django import forms

class SimpleCombobox(forms.Form):
    Col1 = 'Red'
    Col2 = 'Blue'
    Col3 = 'Black'
    Col4 = 'Orange'
      
    COLOR_CHOICES = (
        (Col1, u"Red"),
        (Col2, u"Blue"),
        (Col3, u"Black"),
        (Col4, u"Orange"),
    )
    cities = forms.ChoiceField(choices=COLOR_CHOICES)

# 后续新增下拉框可在此添加新表单类
# class AnotherCombobox(forms.Form):
#     ...

class SimpleTextbox(forms.Form):
    coverletter = forms.CharField(required=False,
              widget=forms.Textarea(
                attrs={'rows': 4, 'cols': 40}))

class LoginForm(forms.Form):
    username = forms.CharField(max_length=65)
    password = forms.CharField(max_length=65, widget=forms.PasswordInput)

步骤2:配置URL路由

在项目或应用的urls.py中添加AJAX请求路由:

from django.urls import path
from . import views

urlpatterns = [
    path('home/', views.home, name='home'),
    path('get-color-message/', views.get_color_message, name='get-color-message'),
    # 其他路由...
]

步骤3:修改前端HTML与添加原生JS

修改home.html,阻止表单默认刷新行为,使用Fetch API发送异步请求并更新textarea内容:

修改后的home.html

{% extends 'app1/base.html' %}

{% load static %}

{% block content %}

<div class="container p-5">
  <div class="row mx-auto">
    <div class="col-6">
      <form class="form-group" id="color-form">
        {% csrf_token %}
        <select name="color" class="form-select" id="color-select">
          {% for i in color_choices %}
          <option value="{{i}}">{{i}}</option>
          {% endfor %}
        </select>
        <textarea class="form-control" name="msg" id="message-area" cols="30" rows="10"></textarea>
        <button class="btn btn-primary mt-3" type="button" id="submit-btn">Submit</button>
      </form>
    </div>
  </div>
</div>

<script>
// 获取DOM元素
const submitBtn = document.getElementById('submit-btn');
const messageArea = document.getElementById('message-area');
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;

submitBtn.addEventListener('click', async () => {
  const selectedColor = document.getElementById('color-select').value;
  
  try {
    const response = await fetch('{% url "get-color-message" %}', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-CSRFToken': csrfToken,
        'X-Requested-With': 'XMLHttpRequest' // 标识AJAX请求
      },
      body: `color=${encodeURIComponent(selectedColor)}`
    });
    
    if (!response.ok) throw new Error('请求失败');
    
    const data = await response.json();
    messageArea.value = data.message;
  } catch (error) {
    messageArea.value = '获取内容失败,请重试';
    console.error(error);
  }
});
</script>
{% endblock content%}

核心优势说明

  1. 无刷新实现:将按钮类型改为button避免默认表单提交,通过Fetch API发送异步请求,直接更新textarea内容,完全避免页面刷新。
  2. 集中管理配置:所有下拉选项统一在forms.py中维护,后续新增下拉框时只需扩展表单类,无需拆分或修改大量JS代码。
  3. 合法请求保护:请求中携带Django的CSRF令牌,符合框架安全要求。
  4. 扩展性强:后续新增多下拉框时,只需在视图中添加对应逻辑,前端JS可复用核心Fetch请求逻辑,仅需调整提交参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:23:22