Ajax
通过ajax, 我们可以异步的通过接口来实现对数据的增删改查
- ajax
delete–> url /stu/student/ID/
- form表单提交
- csrfmiddle开启
- {% csrf_token %} 在页面中会自动加载为下面的标签
value=’duRoaLbyewAO7aLxV0HZyOWB9npPqLs01a27Y3nnqg2h8lTJjkcQdeiKzfpZJdX0’ />
- ajax提交delete
开启了csrfmiddle
csrf = $(‘input[name=”csrfmiddlewaretoken”]’).val()
headers:{‘X-CSRFToken’: csrf}
ajax更新patch
ajax创建post
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>显示所有学生信息</title>
</head>
<body>
<input id="showStus" value="获取所有学生信息" type="button">
<div class="div_stus"></div>
<div id="div_update"></div>
<div>
<input type="text" id="name">
<input type="text" id="tel">
<input type="button" id="new_create" value="创建">
</div>
<script src="/static/js/jquery.min.js"></script>
<script>
csrf = $('input[name="csrfmiddlewaretoken"]').val();
function update_stu(i) {
s = '姓名:<input type="text" id="s_name" name="name">\
电话:<input type="text" id="s_tel" name="tel">\
<input type="button" value="提交" onclick="update(' + i + ')">';
$('#div_update').html(s)
}
// 更改
function update(i) {
// 获取csrf
csrf = $('input[name="csrfmiddlewaretoken"]').val();
s_name = $('#s_name').val();
s_tel = $('#s_tel').val();
$.ajax({
url:'/stu/student/' + i + '/',
type:'PATCH',
// 注意如果有数据传输,要有data
data:{'s_name': s_name,'s_tel':s_tel},
dataType:'json',
// 如果不加,有可能服务器端会不接受访问
headers:{'X-CSRFToken': csrf},
success:function () {
alert("修改成功")
},
error:function () {
alert("修改失败")
}
});
}
function del_stu(id){
csrf = $('input[name="csrfmiddlewaretoken"]').val();
$.ajax({url:'/stu/student/' + id + '/',
type:'delete',
headers:{'X-CSRFToken':csrf},
dataType: 'json',
success: function () {
alert('删除成功');
},
error:function () {
alert('删除失败');
},});
};
$(function () {
// 创建
$('#new_create').on('click', function () {
csrf = $('input[name="csrfmiddlewaretoken"]').val();
s_name = $('#name').val();
s_tel = $('#tel').val();
$.ajax({
url:'/stu/student/',
type:'POST',
data:{'s_name':s_name, 's_tel':s_tel},
dataType:'json',
headers:{'X-CSRFToken':csrf},
success:function () {
alert('创建成功')
},
error:function () {
alert('创建失败')
},
})
});
// 显示所有信息
$('#showStus').on('click', function () {
$.get('/stu/student/', function (obj) {
var msg = obj.data
s = '<table><tr><td>ID</td><td>姓名</td><td>电话</td><td>操作</td></tr>'
for (var i=0; i<msg.length; i+=1){
s += '<tr><td> ' + msg[i].id + '</td>\
<td>' + msg[i].s_name + '</td>\
<td>' + msg[i].s_tel + '</td>\
<td><a href="javascript:;" onclick="update_stu(' + msg[i].id + ')">编辑|</a>\
<a href="javascript:;" onclick="del_stu(' + msg[i].id + ')">删除</a>\
</td></tr>'
}
s += '</table>';
$('.div_stus').html(s);
}, 'json');
});
});
</script>
{% csrf_token %}
</body>
</html>
用ajax传带文件的表单数据
方法一
$("#form-avatar").submit(function(e){
// 用ajax传输表单数据时要阻止表单submit的默认行为,不然或提交两次
e.preventDefault();
$(this).ajaxSubmit({
url:'/user/user/',
type:'PUT',
dataType:'json',
success:function (data) {
if (data.code == 200) {
$('#user-avatar').attr('src', data.url);
}
}
})
方法二
$.ajax({
url:'',
type:'POST',
data: new FormData($('#form-avatar')[0]),
cache: false,
processData: false,// 告诉jQuery不要去处理发送的数据
contentType: false,// 告诉jQuery不要去设置Content-Type请求头
success:function (data){
},
error:function (data) {
}
})
restful
返回结构
- 下面的返回结构是不经任何修改,直接从数据库提取出来,并序列化成json的格式,
- 如果将这样的数据返回给前端,对前端是不友好的
[{“id”:11,”s_name”:”测试1”,”s_tel”:”12121212”,”s_addr”:”“},{“id”:12,”s_name”:”顺悟空”,”s_tel”:”17897654331”,”s_addr”:”“},{“id”:15,”s_name”:”张三丰”,”s_tel”:”134456778”,”s_addr”:”“}]
所以要修改为以下格式
{
“code”:0,
“data”:{“display_fields”:[{“field_key”:”vehicle_type”,”id”:72,”field_name”:”车型”}]},
“msg”:”请求成功”
}
需要继承JSONRenderer,重构render方法
# settings.py中
# 配置restful api 返回结果
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'utils.renderResponse.CustomJsonRenderer',
)
}
# utils下创建的renderResponse.py文件
from rest_framework.renderers import JSONRenderer
class CustomJsonRenderer(JSONRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
"""
格式
{
'code':xxx,
'msg': 请求成功,
'data':{返回数据}
}
"""
if renderer_context:
if isinstance(data, dict):
# 如果数据中有msg,删除msg,并取到,如果没有msg为请求成功
msg = data.pop('msg', '请求成功')
code = data.pop('code', 0)
else:
msg = '请求成功'
code= 0
response = renderer_context['response']
response.status_code = 200
res = {
'code': code,
'msg': msg,
'data': data
}
# 返回新的格式
return super().render(res, accepted_media_type, renderer_context)
else:
return super().render(data, accepted_media_type,renderer_context)
- patch 变量为空
"""
如果通过接口修改数据时,如果提交的s_name字段为空,会返回下面的结果
,但是返回的内容是英文,对于前端也是不友好的,所以我们要通过重写error_messages,
给前端提供更加友好的接口信息
{
{
"msg": "请求成功",
"data": {
"s_name": [
"This field may not be blank."
]
} "code": 0,
}
"""
# serializers.py文件
from rest_framework import serializers
from stu.models import Student
class StudentSerializer(serializers.ModelSerializer):
# 可以在restful中对传递给数据库的数据进行过滤
# 如果数据为空,返回blank对应的提示
# 如果数据大于10个字符,返回max_length对应的提示
# 注意:数据是先经过后端,由restful框架对其进行筛选,如果数据内容
# 不通过,不会将数据传给数据库,所有在这里设置的max_length不会与
# 定义字段时设置的长度冲突
s_name = serializers.CharField(error_messages={
'blank': '用户名不能为空',
'max_length': '用户名不能超过10个字符'
}, max_length=10)
s_tel = serializers.CharField(error_messages={
'blank': '电话不能为空'
})
class Meta:
model = Student
fields = ['id', 's_name', 's_tel']
def to_representation(self, instance):
data = super().to_representation(instance)
try:
data['s_addr'] = instance.studentinfo.i_addr
except Exception as e:
data['s_addr'] = ''
return data