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

Django中JS实现头像更新后无法写入数据库的问题求助

Django头像上传成功但未写入数据库的问题排查与修复

问题现象

开发Django应用时,实现了更换头像功能:点击按钮弹出文件选择框,选择文件后弹出"上传成功"提示,但数据库里的用户头像字段并未更新。

相关代码

模板JS代码

<script>
  // JavaScript
  document.addEventListener("DOMContentLoaded", function () {
    const uploadButton = document.getElementById("uploadButton");
    const fileInput = document.getElementById("fileInput");

    uploadButton.addEventListener("click", function () {
      fileInput.click(); 
    });

    fileInput.addEventListener("change", function () {
      const formData = new FormData(document.getElementById("profileForm"));

      fetch("{% url 'update_profil_photo' %}", {
        method: "POST",
        body: formData,
        headers: {
          "X-CSRFToken": '{{ csrf_token }}'
        }
      })
      .then(response => response.json())
      .then(data => {
        if (data.success) {
          alert("Sucessfully updated!");
        } else {
          alert("An error occured, please try again.");
        }
      })
      .catch(error => {
        alert("an error occured, please try again.");
      });
    });
  });
</script>

模板HTML代码

<form method="post" enctype="multipart/form-data" action='{% url "update" %}' id="profileForm">
  {% csrf_token %}
  
  <button class="btn btn-info" type="button" id="uploadButton">
    <i class="fa fa-fw fa-camera"></i>
    
    <span>Change Photo</span>
  </button><input id="fileInput" type="file" style="display: none;">
</form>

视图函数代码

@login_required
def update_profil_photo(request):
    user_profile = get_object_or_404(UserProfile, user=request.user)
    user = request.user
    if request.method == 'POST':
        profile_form = UserProfilePictureUpdateForm(request.POST, request.FILES, instance=user_profile)
        if profile_form.is_valid():
            profile_form.save()
            messages.success(request, 'Update is successful')
            return JsonResponse({'success': True})
                     
    else:
        profile_form = UserProfilePictureUpdateForm(instance=user_profile)
    return render(request, 'profile.html', {'profile_form': profile_form})

问题根源与修复方案

1. 文件输入框缺少name属性

HTML中的<input type="file">没有设置name属性,导致FormData无法将文件数据传递给后端,表单验证时无法识别上传的文件。

修改HTML代码:给fileInput添加name属性,值要和UserProfilePictureUpdateForm中定义的头像字段名一致(比如假设字段名为profile_picture):

<input id="fileInput" type="file" name="profile_picture" style="display: none;">

2. 表单验证失败时未返回错误响应

当前视图中,如果表单验证失败,会直接返回渲染页面的响应,而前端fetch请求会将其视为成功响应(HTTP状态码为200),进而弹出"上传成功"的错误提示,同时数据库没有更新。

修改视图函数:在表单验证失败时,返回包含错误信息的JsonResponse:

@login_required
def update_profil_photo(request):
    user_profile = get_object_or_404(UserProfile, user=request.user)
    if request.method == 'POST':
        profile_form = UserProfilePictureUpdateForm(request.POST, request.FILES, instance=user_profile)
        if profile_form.is_valid():
            profile_form.save()
            return JsonResponse({'success': True})
        # 表单验证失败时返回错误信息
        return JsonResponse({'success': False, 'errors': profile_form.errors})
                     
    else:
        profile_form = UserProfilePictureUpdateForm(instance=user_profile)
    return render(request, 'profile.html', {'profile_form': profile_form})

3. 检查表单类字段配置

确保UserProfilePictureUpdateForm正确指定了头像字段,示例如下:

from django import forms
from .models import UserProfile

class UserProfilePictureUpdateForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['profile_picture']  # 替换为你UserProfile模型中的头像字段名

4. 可选:更新前端头像显示

上传成功后,前端可以更新页面上的头像元素,让用户直观看到变化。比如假设头像元素的id是profileAvatar,可以在data.success为true时添加:

.then(data => {
  if (data.success) {
    alert("Sucessfully updated!");
    // 更新页面头像
    document.getElementById('profileAvatar').src = `/media/${user_profile.profile_picture}`;
  } else {
    alert("上传失败:" + JSON.stringify(data.errors));
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:02:01