Django模板/HTML场景下如何基于JS请求响应无回刷生成页面动态行
Django 无回发追加表格行实现方案(无需JS拼接HTML)
完全可以实现你的需求,核心思路是借助Django服务端渲染模板片段的能力,将表格结构逻辑全部抽离到独立模板文件中,前端仅通过AJAX请求获取渲染完成的HTML片段直接插入页面,全程不会触发页面回发。
具体实现步骤
1. 抽离独立表格模板片段
新建单独的模板文件,路径可设为templates/partials/team_table_rows.html,所有表格相关的结构都用Django原生模板语法编写,和你平时用include引入的模板写法完全一致:
<!-- 可以把thead放在父页面的<table>标签里,避免重复插入,这里只保留行逻辑更合理 --> {% for item in collection %} <tr id="{{ item.ftId }}"> <td style="width: 26%;">{{ item.name }}</td> <td style="width: 30%;">{{ item.email }}</td> <td style="width: 12%;">{{ item.status }}</td> <td style="width: 20%;"> <span class="name" value="{{ item.gId }}" id="lblGroups{{ item.fId }}">{{ item.gName }}</span> <div id="divGroups{{ item.fId }}" style="display:none"> <select id="dropdownList{{ item.ftId }}" class="lstG" style="height: 20px;"> {% for group in groups %} <option value="{{ group.pk }}" {% if item.gId == group.pk %}selected{% endif %}>{{ group.f.name }}</option> {% endfor %} </select> </div> </td> <td style="width: 20%;"> <input id="chkIsActive{{ item.ftId }}" type="checkbox" {% if item.isActive %}checked{% endif %} disabled> </td> <td style="width: 12%;"> <div id="EditDelete{{ item.ftId }}"> <button type=button style="background-color:#0d7458;border-color:#0d7458;" onclick="editFTeams({{ item.ftId }})"> <img src="/static/images/Icons/edit-icon.svg" width="12" height="12"> </button> </div> <div id="UpdateSave{{ item.ftId }}" style="display:none"> <button type=button style="background-color:#0d7458;border-color:#0d7458;" onclick="UpdateTeams({{ item.ftId }})" > <img src="/static/images/Icons/save.svg" width="12" height="12"/> </button> <button type=button style="background-color:#0d7458;border-color:#0d7458;" onclick="CancelFTeams({{ item.ftId }})" > <img src="/static/images/Icons/cancel.svg" width="12" height="12"/> </button> </div> </td> </tr> {% endfor %}
2. 修改后端接口逻辑
调整你原有的GetCollection接口,用Django内置的render_to_string方法渲染上面的模板片段,直接返回渲染完成的HTML字符串即可:
from django.template.loader import render_to_string from django.http import HttpResponse def get_collection(request, my_id): # 保留你原有获取groups、collection数据的逻辑 groups = # 你的原查询逻辑 collection = # 你的原查询逻辑 # 渲染模板片段 rendered_html = render_to_string( "partials/team_table_rows.html", context={"groups": groups, "collection": collection} ) return HttpResponse(rendered_html)
3. 简化前端AJAX代码
删除原有JS中所有解析JSON、拼接HTML的逻辑,直接将后端返回的HTML插入对应容器即可:
function GetCollection(myId) { var Urlgetallcom = "/sc/GetCollection/" + myId ; $.ajax({ url: Urlgetallcom, type: "GET", data: { Id: myId }, success: function (html) { // 首次插入时可以先加thead,建议直接把thead写在父页面的<table>里更稳妥 if (!$('#allTeammates thead').length) { $('#allTeammates').append(` <thead> <tr> <th style="width: 26%;">Name</th> <th style="width: 30%;">Email</th> <th style="width: 12%;">Status</th> <th style="width: 20%;">Role</th> <th style="width: 20%;">Permission</th> <th style="width: 12%;"></th> </tr> </thead> `) } // 直接插入后端返回的行HTML $('#allTeams').append(html) }, error: function (xhr, errmsg, err) { $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: " + errmsg + " <a href='#' class='close'>×</a></div>"); console.log(xhr.status + ": " + xhr.responseText); } }); };
注意事项
- 表格thead可以直接写在父页面的
<table id="allTeammates">标签内,不需要通过JS动态插入,避免重复渲染的判断逻辑 - 你原有JS代码中存在两个笔误:success回调参数定义为
json1但实际使用了未定义的json、遍历groups时使用了未定义的g[j],改用服务端模板渲染后可以避免这类JS语法问题 - 模板文件可以正常复用,和你用
{% include %}引入模板的使用方式完全一致,后期修改表格结构只要调整模板文件即可,不需要修改JS代码
内容的提问来源于stack exchange,提问作者Khaksar
相关产品推荐
相关产品推荐

