Django之Ajax
1.Ajax简介
- AJAX,英文全称Asynchronous Javascript And XML,中文意思是:异步的Javascript和XML。即使用Javascript语言与服务器进行异步交互,传输的数据为XML,不过现在用的比较多的就是json。
- Ajax优点:在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。这一特点给用户的感受是在不知不觉中完成请求和响应过程。
- 两大特点:
- 局部刷新
- 异步请求:客户端发出一个请求后,无须等待服务器响应结束,就可以发出第二个请求。
- 两大特点:
2.用户登录页面示例
-
html代码:
{% load static %} <!DOCTYPE html> <html lang = 'en'> <head> <meta charset = "UTF-8"> <title>小骚浩</title> </head> <body> <h1> 登录页面 </h1> {% csrf_token %} #安全认证 <hr> 用户名:<input type = 'text' id = 'username'> 密码: <input type = "password" id = "password"> <button id = "sub"> 提交 </button> <span id = 'error' style = "color : red; font_size : 12px;"> </span> </body>
-
js代码:
<script src = "https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script> <script> $('#sub').click(function(){ var username = $('#username').val(); var password = $('password').val(); var csrf = $('[name = "csrfmiddlewaretoken"]').val(); $.ajax({ url:'{% url 'login' %}', #请求路径,如果将js代码放到另一个文件中,url模块渲染不会被渲染,即系统会报错 type:'post', #请求方法 data:{'username':username,'password':password,'csrfmiddlewaretoken':csrf},#请求数据,不需要携带数据的请求,不需要写data参数 success:function(res){#res参数拿到的是响应数据 if (res !== 'ok'){ $('error').text("用户名或密码错误") }else{ location.href='/home/';#跳转到 home页面 } } }) }) </script> </html>
-
views.py代码:
from django.http import JsonResponse from django.views import View from django.shortcuts import render,redirect,HttpResponse class Login(View): def get(self,request): return render(request,'login.html') def post(self,request): username = request.POST.get('username') password = request.POST.get('password') if username == "小骚浩" and password == "5201314": return HttpResponse('ok') else: return HttpResponse("不 ok")
3. ajax通过csrf_token认证的三种方式
-
方式一:
-
html代码:
{% csrf_token %} 用户名: <input type="text" id="uname"> 密码: <input type="password" id="pwd"> <button id="sub">提交</button>
-
js代码:
$('#sub').click(function () { var uname = $('#uname').val(); var pwd = $('#pwd').val(); # 获取到{% csrf_token %}这个模板渲染语法渲染之后的input标签对应的值 var xxx = $('[name="csrfmiddlewaretoken"]').val(); $.ajax({ url:'{% url "login" %}', // 127.0.0.1:8000/login/ type:'post', # 给post请求提交的数据中添加上csrf_token认证所需要的键值对 data:{'uname':uname,'pwd':pwd,'csrfmiddlewaretoken':xxx}, success:function (res) { console.log('>>>>',res); if (res !== 'ok'){ $('#error').text('用户名或者密码有误!') }else { location.href='/home/'; } } }) })
-
-
方式二:
-
html代码:
用户名: <input type="text" id="uname"> 密码: <input type="password" id="pwd"> <button id="sub">提交</button>
-
js代码:
$('#sub').click(function () { var uname = $('#uname').val(); var pwd = $('#pwd').val(); $.ajax({ url:'{% url "login" %}', // 127.0.0.1:8000/login/ type:'post', # data数据部分的csrf_token认证的键值对的值直接写{{ csrf_token }} ,经过模板渲染之后,它直接就是那个input标签的value值 data:{'uname':uname,'pwd':pwd,'csrfmiddlewaretoken':'{{ csrf_token }}'}, success:function (res) { console.log('>>>>',res); if (res !== 'ok'){ $('#error').text('用户名或者密码有误!') }else { location.href='/home/'; } } }) })
-
-
方式三(ajax上传文件示例):
-
html代码:
{% csrf_token %} 用户名:<input type="text" name="username"> 头像: <input type="file" name="file_obj"> <input type="submit" id="btn">
-
js代码:
$('#btn').click(function () { var formdata = new FormData(); #实例化FormData对象 var uname = $('[name="username"]').val(); // var file_obj = $('[name="file_obj"]').val(); //"C:fakepath .jpg" 拿到的文件的本地路径 var f_obj = $('[name="file_obj"]')[0].files[0] ; // 这是文件对象 formdata.append('username',uname); formdata.append('file_obj',f_obj); formdata.append('csrfmiddlewaretoken',$('[name="csrfmiddlewaretoken"]').val()); $.ajax({ url:'/upload/', type:'post', // data:{uname:uname,file_obj:f_obj,'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()}, // 上传文件时的固定搭配 formdata processData:false, contentType:false, data:formdata, success:function (res) { console.log(res) } }) })
-
4. form表单上传文件
-
html代码:form表单标签的 enctype="multipart/form-data"这个属性要写才能上传文件,content-type请求头中的携带数据的消息格式>
<form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} 用户名:<input type="text" name="username"> 头像: <input type="file" name="file_obj"> <input type="submit"> </form>
-
views.py代码:
def upload(request): if request.method == 'GET': return render(request,'upload.html') else: print(request.POST) print(request.FILES) file_obj = request.FILES.get('file_obj') # f = open('xx','rb') # for i in f: # print(i) print(file_obj.name) with open(file_obj.name,'wb') as f: # for i in file_obj: # f.write(i) for i in file_obj.chunks(): #65536字节 f.write(i) return HttpResponse('ok')
5. JsonResponse
views代码:
from django.http import JsonResponse
def data(request):
if request.method == 'GET':
d1 = {'name':'chao','age':18}
# d1_str = json.dumps(d1)
# return HttpResponse(d1_str,content_type='application/json')
return JsonResponse(d1) #干了上面两步,序列化以及加content_type响应头这样,ajax在处理数据时会自动将json数据反序列化,那么如果jsonresponse的数据不是字典,需要加上safe参数
return JsonResponse(d1,safe=False)
success:function(res){
这个res就是反序列化之后的数据了,直接可以用
}
6.JSON序列化时间
views代码:
序列化时间
import json
from datetime import datetime
from datetime import date
#对含有日期格式数据的json数据进行转换
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field,datetime):
return field.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field,date):
return field.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self,field)
d1 = datetime.now()
dd = json.dumps(d1,cls=JsonCustomEncoder)
print(dd)
7.js魔法框
html代码:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书籍展示</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'tankuang/dist/sweetalert.css' %}">
<style>
a{
text-decoration: none;
color: white;
}
</style>
</head>
<body>
<h2>查看书籍中。。。</h2>
<div class="col-xs-8 col-xs-offset-2 " style="padding-top: 15px;">
<div>
<div class="panel-body">
<div class="row pull-left col-xs-1" style="padding-left: 0">
<a href="{% url 'addBook' %}"><button type="button" class="btn btn-primary">添加书籍
</button></a>
</div>
<div class="row pull-left col-xs-1 col-xs-offset-1" style="padding-left: 0">
<a href="{% url 'author' %}"><button type="button" class="btn btn-primary">展示作者
</button></a>
</div>
<div class="row pull-left col-xs-1 col-xs-offset-1" style="padding-left: 0">
<a href="{% url 'addAuthor' %}"><button type="button" class="btn btn-primary">添加作者
</button></a>
</div>
<div class="row pull-right col-xs-6" style="padding-right: 0">
<form action="" method="post">
{% csrf_token %}
<div class="row col-xs-6 pull-right">
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入查询条件" name="info">
<span class="input-group-btn">
<a href="{% url 'book' %}" role="button" >
<button class="btn btn-success" type="submit">Go
</button></a>
</span>
</div>
</div>
<div class="btn-group pull-right" >
<select name="choose" id="choose" style="height: 34px;text-align: center;line-height: 34px;">
<option value="0">请选择以下内容</option>
<option value="1">作者</option>
<option value="2">书籍名称</option>
<option value="3">书籍价格</option>
<option value="4">出版社日期</option>
<option value="5">出版社</option>
<option value="6">出版城市</option>
</select>
</div>
</form>
</div>
</div>
<div>
<table class="table table-striped table-hover table-condensed">
<thead>
<tr>
<th>编号</th>
<th>书籍名称</th>
<th>书籍作者</th>
<th>价格</th>
<th>出版日期</th>
<th>出版社</th>
<th>出版城市</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for i in ret %}
<tr class="active ">
<td class="first_child">{{ forloop.counter}}</td>
<td>{{ i.title}}</td>
<td>{% for j in i.authors.all %}
{{ j.name }}
{% if forloop.last %}
{% else %}
,
{% endif %}
{% endfor %}</td>
<td>{{ i.price}}</td>
<td>{{ i.publishDate|date:'Y-m-d' }}</td>
<td>{{ i.publishs.name }}</td>
<td>{{ i.publishs.city }}</td>
<td>
<a href="{% url 'Editbook' i.id %}" class="btn btn-warning btn-sm">编辑</a>
<button bookid = "{{ i.id }}" class="delete_btn btn btn-danger btn-sm">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
js代码:
<script src="{% static 'jquery.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'tankuang/dist/sweetalert.min.js' %}"></script>
<script>
$(".delete_btn").on("click",function(){
var ths = $(this);
swal({
title:"想好了吗?",
text:"请陛下三思!",
type:"warning",
showCancelButton:true,
confirmButtonClass:"btn_danger",
confirmButtonText:"再见",
cancelButtonText:"取消",
closeOnConfirm:false
},
function(){
var deleteId = ths.attr('xxoo');
$.ajax({
url:'/delbook/',
type:'post',
data:{'id':deleteid},
success:function(data){
if(data.status === '1'){
swal("删除成功",'success');
ths.parent().parent().remove();
var tr_first_id = $('tr_first_child');
for (var i = 0;i < tr_first_id.length; i++){
$('tr .first_child').eq(i).text(i+1);
}
}else{
swal('删除失败','error');
}
}
})
})
})
</script>
</html>
views.py代码:
from django.shortcuts import render,redirect,HttpResponse
from django.http import JsonResponse
def delbook(request):
ret_data = {'status':None,}
print(ret_data)
if request.method == "POST":
try:
book_id = request.POST.get('id')
models.Book.objects.filter(id=book_id).delete()
ret_data['status'] = '1'
except Exception:
ret_data['status'] = '2'
print(ret_data)
return JsonResponse(ret_data)
urls.py代码:
from app01 import views
urlpatterns = [
url(r'^delbook/', views.delbook,name='delbook'),
]