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

Django中AJAX请求视图无终端打印且头像未更新问题

问题分析与修复方案

核心问题

AJAX请求触发了success,但后端未接收到文件,原因在于前端FormData传递方式错误、事件绑定逻辑有误,同时后端用户获取逻辑和前端模板判断存在小问题。


前端JS修复(child-profile.html)

$(document).ready(function () {
    console.log('jquery is loaded');
    const imageButton = document.getElementById("image-button");
    const fileInput = document.getElementById("file-input");

    // 图片按钮触发文件选择框
    imageButton.addEventListener("click", function (e) {
        e.preventDefault();
        fileInput.click();
    });

    // 文件选择后直接提交
    fileInput.addEventListener("change", function (e) {
        e.preventDefault();
        const file = fileInput.files[0];
        console.log(file);
        
        // 校验图片类型
        if (!(file.type === "image/jpeg" || file.type === "image/jpg" || file.type === "image/png")) {
            alert("仅支持JPEG/JPG/PNG格式图片");
            $("#file-input").val(""); // 修正选择器拼写错误
            return false; // JS布尔值为小写false
        }

        // 构建FormData(直接包含文件和CSRF Token)
        const formData = new FormData();
        formData.append("newPic", file);
        formData.append("csrfmiddlewaretoken", $("input[name=csrfmiddlewaretoken]").val());
        
        // 直接调用AJAX提交,无需触发按钮submit事件
        submitAvatar(formData);
    });

    function submitAvatar(formData) {
        console.log("开始提交头像");
        $.ajax({
            url: "{% url 'users:profile' %}",
            data: formData, // 直接传递FormData对象,而非嵌套在普通对象中
            method: "POST",
            contentType: false,
            processData: false,
            success: function (data) {
                alert("头像更新成功");
                // 实时更新页面头像显示
                imageButton.src = data.profile_pic_url;
            },
            error: function (xhr, status, error) {
                console.log("AJAX错误: ", status, error);
                alert("上传失败:" + error);
            },
        });
    }
});

后端视图修复(views.py)

@login_required
def profile(request):
    # 直接使用当前登录用户,无需额外查询(若为访问他人profile需调整)
    user = request.user
    if request.method == 'POST':
        new_pic_file = request.FILES.get('newPic')
        if new_pic_file:
            print('testing 123', new_pic_file.name)
            user.profile_pic = new_pic_file
            user.save()
            # 返回新头像URL,供前端实时更新
            return JsonResponse({
                'status': 'success',
                'profile_pic_url': user.profile_pic.url
            })
        else:
            return JsonResponse({'status': 'error', 'message': '未选择文件'})
    context = {'user': user}
    return render(request, 'profile-pages/child-profile.html', context)

模板判断逻辑修复

原模板中{% elif request.user.profile_pic.url == None %}会触发空字段访问错误,改为:

{% if request.user.profile_pic %}
<img id="image-button" src="{{ request.user.profile_pic.url }}" style="width: 100px; height: 100px; border: 1px solid black; cursor: pointer;" />
{% else %}
<img src="{% static '/profile-images/default.png' %}" />
{% endif %}

必要配置检查

  1. 确保用户模型的profile_pic字段定义正确:
# models.py
class afbUsers(AbstractUser):
    profile_pic = models.ImageField(upload_to='profile_pics/', blank=True, null=True)
  1. 在settings.py中配置媒体文件路径:
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
  1. 在项目根urls.py中添加媒体文件路由:
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 你的其他路由
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:49:54