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

如何用Fetch或Ajax全局修改Django用户Profile模型的level字段

你的思路完全正确——要永久更新用户的level字段,必须通过Django后端视图操作数据库,前端的Fetch只是用来把新的level值传给后端的工具。下面是具体的实现步骤:

1. 编写处理更新的Django视图

在你的views.py里新增一个视图函数,专门处理level的更新请求:

from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
import json
from .models import Profile

@login_required
def update_profile_level(request):
    if request.method == 'POST':
        try:
            # 解析前端传来的JSON数据
            data = json.loads(request.body)
            new_level = data.get('new_level')
            
            # 验证数据合法性
            if not isinstance(new_level, int) or new_level < 1:
                return JsonResponse({'status': 'error', 'message': '无效的level值'}, status=400)
            
            # 获取当前用户的Profile并更新(没有则自动创建)
            profile, created = Profile.objects.get_or_create(user=request.user)
            profile.level = new_level
            profile.save()
            
            return JsonResponse({'status': 'success', 'new_level': profile.level})
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
    else:
        return JsonResponse({'status': 'error', 'message': '仅支持POST请求'}, status=405)

这里用get_or_create避免了用户未生成Profile的异常,@login_required确保只有登录用户能调用这个接口。

2. 配置URL路由

在urls.py里添加对应的路由:

from django.urls import path
from . import views

urlpatterns = [
    # 原有的game页面路由
    path('game/', views.game, name='game'),
    # 新增的level更新接口路由
    path('update-level/', views.update_profile_level, name='update_level'),
]
3. 修改前端Fetch代码

首先在game.html里引入JS时,把更新接口的URL通过data属性传给JS:

<script src="{% static 'games/game.js' %}" data-url="{% url 'update_level' %}" data-level="{{ level }}"></script>

然后修改game.js的Fetch逻辑,传递目标level值并处理响应:

const data = document.currentScript.dataset;
const currentLevel = parseInt(data.level);
const updateUrl = data.url;

// 示例:假设要把level更新为目标值(这里可以换成你需要的逻辑,比如游戏通关后的level+1)
const targetLevel = currentLevel + 1;

fetch(updateUrl, {
    method: "POST",
    credentials: "same-origin",
    headers: {
        "X-Requested-With": "XMLHttpRequest",
        "X-CSRFToken": getCookie("csrftoken"),
        "Content-Type": "application/json" // 必须声明发送的是JSON格式
    },
    body: JSON.stringify({new_level: targetLevel})
})
.then(response => response.json())
.then(result => {
    if (result.status === 'success') {
        console.log('Level更新成功:', result.new_level);
        // 可选:更新页面上的level显示,比如修改某个元素的内容
        // document.getElementById('current-level').textContent = result.new_level;
    } else {
        console.error('更新失败:', result.message);
    }
})
.catch(error => {
    console.error('请求出错:', error);
});

// 确保CSRF令牌获取函数正常工作
function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
关于POST请求和上下文的关系

这里给你理清楚核心逻辑:

  • 上下文是Django渲染页面时从数据库读取数据,传给模板的一次性静态值。页面加载完成后,上下文里的level就只是浏览器内存中的临时数据,刷新就会消失。
  • 要让level永久生效,必须把新值传给后端,由后端修改数据库里的Profile记录。下次用户加载页面时,game视图会从数据库读取更新后的level,再通过上下文传给前端。
  • 前端的Fetch请求只是负责把新值送到后端,真正的永久修改是后端操作数据库完成的。
额外注意事项
  • 数据验证:后端一定要校验前端传来的new_level合法性,防止恶意传入负数、字符串等非法值。
  • 错误处理:前后端都要处理异常情况,比如网络中断、数据库操作失败等。
  • 静态文件:确保JS文件路径正确,用{% static %}模板标签引入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:45:17