ajax和DOM结合更新页面是我们都非常熟悉的,那么,假如前端页面用到了django模板的话,好像就不好直接用DOM来更新由模板产生的页面元素了。这时,我们需要更新的是django的模板,怎么办呢?在经过一番google之后,我得到了想要的答案,感谢那些优秀的博客和社区,感谢拥有灵敏嗅觉的google!
本文主要参考了:
现通过一个Student的例子总结如下:
学生拥有用户名(username)和年龄(age)两个字段,学生的模型(model)代码如下
from django.db import models
# Create your models here.
class Student(models.Model):
username=models.CharField(max_length=30)
age=models.IntegerField()
前端页面由主页(index.html)和两个模板文件studentForm.html和studentList.html组成。studentForm.html负责产生用于填写学生信息的表单,studentList.html是显示当前所有学生信息的列表
index.html
{% include "demo/studentForm.html" %}
<div id="student-list-wrapper">
{% include "demo/studentList.html" %}
</div>
studentForm.html
<form>
{% csrf_token %}
username:{{studentForm.username}}
age:{{studentForm.age}}
<button type="button" id="id_addBtn">Add</button>
</form>
studentList.html
<ol id="student-list">
{% for student in studentList %}
<li>{{ student.username }},{{student.age}}</li>
{% endfor %}
</ol>
现在我在表单中添加学生信息,并且在添加成功后利用ajax无刷新地更新学生列表
views.py中负责处理前端发来请求的代码如下
from django.shortcuts import render
from django.template.loader import render_to_string
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from demo.forms import StudentForm
from demo.models import Student
import json
# Create your views here.
...(省略非主要代码)
@csrf_exempt
def add(request):
stuObj=json.loads(request.body) # 将post方式包含在请求体中的json字符串转换为
python对象
try:
Student.objects.create(username=stuObj["username"],age=stuObj["age"]) # python中字典只能通过中括号来引用键,而不能用点号
studentList=Student.objects.all()
studentListRendering=render_to_string("demo/studentList.html",{"studentList":studentList}) # 更新模板
return JsonResponse({"status":"ok","studentListRendering":studentListRendering})
except:
return JsonResponse({"status":"error"})
这里的render_to_string函数是关键,它提供刷新模板(studentList.html)的数据,在注入JsonResponse后返回给前端
JavaScript代码
(function(){
let xhr=new XMLHttpRequest();
//处理响应部分
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if((xhr.status>=200 && xhr.status<300)||xhr.status==304){
responseObj=JSON.parse(xhr.responseText);
if(responseObj.status=="ok"){
alert("add success");
let studentListWrapper=document.getElementById("student-list-wrapper");
studentListWrapper.innerHTML=responseObj.studentListRendering; //更新模板内容
}else{
alert("add failed");
}
}else{
alert("response failed");
}
}
}
//发送数据部分
let addBtn=document.getElementById("id_addBtn");
addBtn.addEventListener("click",function(){
xhr.open("post","add/",true);
let username=document.getElementById("id_username").value;
let age=document.getElementById("id_age").value;
let msg=JSON.stringify({"username":username,"age":age});
xhr.send(msg);
});
})();
可以看到在接收到响应后,利用了来源于render_to_string的数据重置了包含待更新模板(studentList.html)的父元素(studentListWrapper)的innerHTML,这一步就完成了模板的更新
完整的代码放在我的github上
本文同时发表在我的个人博客上
网友评论