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

如何通过JavaScript实现模型URLField(Instagram)的无刷新更新

问题描述

我有一个展示网站管理员信息(用户名、技能、Instagram主页、个人简介)的页面,管理员可通过JavaScript的fetch API编辑并保存个人资料。点击保存按钮后,除了URL类型的Instagram字段外,其余信息均可实时更新,该字段必须刷新页面才能生效。控制台日志显示所有操作均正常,请问如何实现该字段的无刷新更新?


相关代码

about.js

document.addEventListener("DOMContentLoaded", function(){

    const button = document.querySelectorAll("#edit_profile")
    button.forEach(function(button){
        button.onclick = function(){
            // 补充获取当前成员ID
            const memberID = this.dataset.id;
            const username = document.getElementById(`username_${memberID}`);
            const skills = document.getElementById(`skills_${memberID}`);
            const bio = document.getElementById(`bio_${memberID}`);
            // 保存Instagram链接的DOM元素引用,而非仅存href值
            const instagramLink = document.getElementById(`instagram_${memberID}`);
            var instagram = instagramLink.href;

            let edit_username = document.createElement("textarea");
            edit_username.setAttribute("rows", "1");
            edit_username.innerHTML = username.innerHTML
            edit_username.id = `edit_username_${memberID}`;
            edit_username.className = `form-control username`;
            
            let edit_skills = document.createElement("textarea");
            edit_skills.setAttribute("rows","1");
            edit_skills.innerHTML = skills.innerHTML;
            edit_skills.id = `edit_skills_${memberID}`;
            edit_skills.className = "form-control";
            
            let edit_bio = document.createElement("textarea");
            edit_bio.setAttribute("rows","3");
            edit_bio.innerHTML = bio.innerHTML;
            edit_bio.id = `edit_bio_${memberID}`;
            edit_bio.className = "form-control";
            
            let edit_instagram = document.createElement("textarea");
            edit_instagram.setAttribute("rows","1");
            edit_instagram.innerHTML = instagram;
            edit_instagram.id = `edit_instagram_${memberID}`;
            edit_instagram.className = "form-control social-media";

            const saveButton = document.createElement("button");
            saveButton.innerHTML = "Save";
            saveButton.id = `saveButton_${memberID}`;
            saveButton.className = "btn btn-success col-3";
            saveButton.style.margin = "10px";
            
            const editContainer = document.getElementById(`edit_${memberID}`);
            // 清空容器避免重复生成编辑控件
            editContainer.innerHTML = "";
            editContainer.append(edit_username);
            editContainer.append(edit_skills);
            editContainer.append(edit_bio);
            editContainer.append(edit_instagram);
            editContainer.append(saveButton);

            // 保存按钮点击事件
            saveButton.addEventListener("click", function(){
                edit_username = document.getElementById(`edit_username_${memberID}`);
                edit_skills = document.getElementById(`edit_skills_${memberID}`);
                edit_bio = document.getElementById(`edit_bio_${memberID}`);
                edit_instagram = document.getElementById(`edit_instagram_${memberID}`);
            
                fetch(`/edit_profile/${memberID}`,{
                    method: "POST",
                    headers: {
                        'Content-Type': 'application/json',
                        // 补充Django需要的CSRF令牌
                        'X-CSRFToken': getCookie('csrftoken')
                    },
                    body: JSON.stringify({
                        username: edit_username.value,
                        skills: edit_skills.value,
                        instagram: edit_instagram.value,
                        bio: edit_bio.value,
                        itch_profile: document.getElementById(`itch_${memberID}`).href
                    })
                })
                .then(response => response.json())
                .then(result => {
                    console.log(result);
                    if(result.error){
                        // 取消编辑,清空容器
                        editContainer.innerHTML = "";
                    } 
                    else {
                        // 更新普通文本字段
                        username.innerHTML = result.username;
                        document.getElementById(`secusername_${memberID}`).innerHTML = `${result.username}, `;
                        skills.innerHTML = result.skills;
                        bio.innerHTML = result.bio;
                        // 核心:直接更新Instagram链接的href属性
                        instagramLink.href = result.instagram;
                        // 清空编辑容器
                        editContainer.innerHTML = "";
                    }
                })
                .catch(error => console.error('保存失败:', error));
            })
        }
    });
});

// 辅助函数:获取Django 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;
}

about.html

{% for member in team_members %}
      <div class="col" id="border">
<!--管理员可见编辑按钮-->
        {% if user.is_superuser %}
        <div class="position-relative" id="edit_button_{{member.id}}" style="display: block;">
          <button class="btn btn-lg position-absolute top-0 end-0" id="edit_profile" data-id="{{member.id}}" data-username="{{member.username}}">
          <i class="fa fa-edit fa-solid" style="color: white; margin-right: 5px;"></i></button>
        </div>
        {% endif %}
        
        <!--编辑表单容器-->
            <div class="form-group" id="edit_{{member.id}}">
            </div>
     
          <!--展示用户信息-->
            <div id="remove_{{member.id}}" style="display: block;">
              <h3 class="username" id="username_{{member.id}}">{{member.username}}</h3>
              <p class ="skills" id="skills_{{member.id}}">{{member.skills}}</p>
              <p><a class="social-media" href="{{member.instagram}}" id="instagram_{{member.id}}"><i class="fa-brands fa-instagram fa-solid" style="color: #e3c142; margin-right: 5px;"></i></a>
              <a class="social-media" href="{{member.itch_profile}}" id="itch_{{member.id}}"><i class="fa-brands fa-itch-io" style="color: #e3c142;"></i></a>
              <div class="bio">
                  <strong class="username" id="secusername_{{member.id}}"  style="font-size: large;">{{member.username}}, </strong><p id="bio_{{member.id}}">{{member.bio}}</p>
              </div>
            </div>
        </div>
      </div>
{% endfor %}

views.py

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
from .models import Team

@csrf_exempt
def edit_profile(request, member_id):
    if request.method != "POST":
        return JsonResponse({"error": "仅支持POST请求。"}, status=400)
    
    try:
        team_member = Team.objects.get(id=member_id)
    except Team.DoesNotExist:
        return JsonResponse({"error": "用户不存在。"}, status=404)

    try:
        body_unicode = request.body.decode('utf-8')
        body = json.loads(body_unicode)
    except json.JSONDecodeError:
        return JsonResponse({"error": "无效的JSON数据。"}, status=400)
    
    # 安全获取字段值,避免KeyError
    username = body.get('username', team_member.username)
    skills = body.get('skills', team_member.skills)
    instagram = body.get('instagram', team_member.instagram)
    itch_profile = body.get('itch_profile', team_member.itch_profile)
    bio = body.get('bio', team_member.bio)
    
    # 更新数据库
    Team.objects.filter(id=member_id).update(
        username=username,
        skills=skills,
        instagram=instagram,
        itch_profile=itch_profile,
        bio=bio
    )
    
    return JsonResponse({
        "message": "保存成功", 
        "username": username, 
        "skills": skills, 
        "instagram": instagram, 
        "itch_profile": itch_profile, 
        "bio": bio
    }, status=200)

解决方案

问题核心是你之前只更新了存储URL的变量,没有修改页面上<a>标签的href属性:

  1. 保存DOM元素引用:在编辑按钮点击时,获取Instagram链接的DOM元素(const instagramLink = document.getElementById(\instagram_${memberID}`);),而不是仅提取href`值。
  2. 直接修改href属性:在fetch请求成功的回调里,执行instagramLink.href = result.instagram;,这样就能实时更新链接地址,无需刷新页面。

另外补充了两个原代码的潜在问题:

  • 添加了Django必需的CSRF令牌验证,避免请求被拦截。
  • 每次编辑前清空编辑容器,防止重复生成编辑控件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:05:18