Django 系列博客(十四)

前言

本篇博客介绍在 html 中使用 ajax 与后台进行数据交互。

什么是 ajax

ajax(Asynchronous Javascript And XML)翻译成中文就是‘’异步 JavaScript 和 XML‘’。即使用 JavaScript 语言与服务器进行异步交互,传输的数据为 XML(现在更多地使用 json)。

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,也能发出第二个请求。

ajax 除了异步的特点外,还有一个就是:浏览器页面局部刷新。在页面没有进行刷新的情况下进行数据交互。

优点:

  • ajax 使用JavaScript 技术向服务器发送异步请求;
  • ajax 无需刷新整个页面。

基于 jQuery 的 ajax 实现

前端代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="/static/jquery-3.3.1.js"></script> <title>regist</title>
{# <link rel="stylesheet" href="/static/jquery-3.3.1.js">#}
</head>
<body>
<p>用户:<input type="text" id="name"></p>
<p>密码:<input type="password" id="pwd"></p>
<p>确认密码:<input type="password" id="tpwd"></p>
<input type="button" id="submit" value="提交"><span id="error"></span>
</body> <script> $('#submit').click(function () {
console.log($('#submit'));
{#$.ajax({#}
{# url:'/regist/',#}
{# type:'post',#}
{# data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd")},#}
{# success:function (data) {#}
{# console.log(data)#}
{# }#}
$.ajax({
url:'/regist/',
type:'post',
data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd").val()},
success:function (data) {
console.log(data)
}
}) })
</script>
</html>

后端代码

from django.http import JsonResponse
from django.shortcuts import render, redirect
from app01.models import * # Create your views here. def wrapper(func):
def inner(*args, **kwargs):
if args[0].method == 'GET':
return func(*args, **kwargs)
elif kwargs['contentType'] == 'application/json':
import json
args[0].POST = json.loads(args[0].body)
return func(*args, **kwargs)
else:
return func(*args, **kwargs)
return inner import json
# json.loads() def regist(request):
dic = {'status': 200, 'msg': None}
print(request.body)
if request.method == 'GET':
return render(request, 'regist.html')
else:
print('/////')
print(request.POST, 'dddd')
name = request.POST.get('name')
pwd = request.POST.get('pwd')
tpwd = request.POST.get('tpwd') user = UserInfo.objects.filter(name=name).first()
if user:
dic['status'] = 100
dic['msg'] = '用户已存在'
return JsonResponse(dic)
else:
if name and pwd and tpwd:
if pwd == tpwd:
UserInfo.objects.create(name=name, pwd=pwd)
dic['msg'] = '注册成功'
return JsonResponse(dic)
else:
dic['status'] = 101
dic['msg'] = '两次密码不一样'
return JsonResponse(dic)
else:
dic['status'] = 101
dic['msg'] = '密码不正确'
return JsonResponse(dic) @wrapper
def login(request):
dic = {'status': 200, 'msg': None}
if request.method == 'GET':
return render(request, 'login.html')
else:
name = request.POST.get('name')
pwd = request.POST.get('pwd') user = UserInfo.objects.filter(name=name).first()
if not user:
dic['status'] = 100
dic['msg'] = '用户不存在,请注册'
return JsonResponse(dic)
else:
if pwd == user.pwd:
dic['msg'] = '登陆成功'
return JsonResponse(dic)
else:
dic['status'] = 101
dic['msg'] = '密码错误'
return JsonResponse(dic)

js代码

$("#submit3").click(function () {
$.ajax({
url: '/auth/',
type: 'post',
data: {
'user': $("#id_name").val(),
'password': $('#id_password').val()
}, success: function (data) {
{#console.log(data)#}
var data=JSON.parse(data)
if (data.user){
location.href='https://www.baidu.com'
}else {
$(".error").html(data.message).css({'color':'red','margin-left':'20px'})
}
} })
}
)

文件上传

请求头

  1. application/x-www-form-urlencoded

这是最常见的 POST 提交数据的方式了。浏览器的原生表单,如果不设置 enctype 属性,那么最终会以 application/x-www-form-urlencoded方式提交数据。类似于下面:

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8 请求体
  1. multipart/form-data

当我们使用表单上传文件时,必须让表单的 enctype 等于multipart/form-data。

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="user" yuan
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以--boundary 开始,紧接着是内容描述信息,然后回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以--boundary--表示结束。

这种方式一般用于上传文件,各大服务端语言也有很好的支持。

这两种POST 提交的方式,都是浏览器原生支持的,而且先阶段标准中原生表单也只支持这两种方式(通过元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded)。随着越来越多的web站点尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

  1. application/json

application/json是另外一种请求头,不过更多的是作为响应头,因为 json 格式的数据时通用数据格式。不过目前也用来作为请求头,用来告诉服务器端主体是序列化后的 json 字符串。由于 json 规范的流行,除了低版本的 IE 之外的各大浏览器都原生支持 json.stringfy,服务器端语言也都有处理 json数据的函数,使用 json 不会遇到什么麻烦。

json 格式支持比键值对复杂的多的结构化数据,这点对数据传输很有用。

基于form表单上传文件

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="" method="post" enctype="multipart/form-data">
<p>用户名:<input type="text" name="name"></p>
<input type="file" name="myfile">
{# <input type="file" name="myfile2">#}
<input type="submit" value="提交"> </form> </body>
</html>

后端代码

class UploadFile(View):

    def get(self, request):
return render(request, 'upload_file.html') def post(self, request):
file = request.FILES.get('myfile')
# print(file['file'])
from django.core.files.uploadedfile import InMemoryUploadedFile
print(time.time())
filename = str(time.time()).split('.')[0] + file.name
with open(filename, 'wb') as f:
for line in file:
f.write(line)
return HttpResponse('上传成功')

基于ajax 的文件上传

前端代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>uploadfile</title>
<script src="/static/jquery-3.3.1.js"></script>
</head>
<body>
<p>用户名:<input type="text" id="name"></p>
<p>选择文件:<input type="file" id="my_file"></p>
<button id="btn">上传</button><span id="msg"></span>
</body> <script>
$('#btn').click(function () {
var myfile = $('#my_file')[0].files[0];
var formdata = new FormData();
formdata.append('name', $('#name').val());
formdata.append('myfile', myfile);
$.ajax({
url:'/uploadfile/',
type:'post',
processData:false, // 告诉 jQuery 不要处理发送的数据
contentType:false, // 告诉 jQuery 不要设置 Content-Type 请求头
data:formdata,
success:function (data) {
console.log(data);
$('#msg').text(data)
}
})
}) </script>
</html>

后端代码

MEDIA_PATH = '/Users/jingxing/Django/homework/paging/media'

def uploadfile(request):
if request.method == 'GET':
return render(request, 'uploadfile.html')
else: myfile = request.FILES.get('myfile')
print(myfile)
filepath = os.path.join(MEDIA_PATH, myfile.name[32:-3]+'jpg')
with open(filepath, 'wb') as f:
for line in myfile:
f.write(line)
FileInfo.objects.create(name=request.POST.get('name'), filepath=filepath)
return HttpResponse('上传成功')

ajax 提交 json 格式数据

前端代码

$('#submit1').click(function () {
postdata={name1:$("#name").val(),pwd2:$("#pwd").val()}
$.ajax({
url:'/loginjson/',
type:'post',
// 指定提交的编码格式是json格式,
contentType:'application/json',
data:JSON.stringify(postdata),
// data:postdata,
// data:'123',
success:function (data) {
console.log(data) }
})
})

后端代码

def loginjson(request):
dic={'status':100,'msg':None}
if request.method=='POST':
print(request.POST)
print(request.GET)
print(request.body)
xx=request.body.decode('utf-8')
# re是个字典{"name1":"lqz","pwd2":"123"}
re=json.loads(xx)
request.POST=11 print(request.POST)
#
#
# name=re.get('name1')
# pwd=re.get('pwd2')
# print(name)
# print(pwd)
return HttpResponse('ok')

后端返回 json 数据

前端代码

$('#submit').click(function () {
$.ajax({
url:'/login/',
type:'post',
data:{name1:$("#name").val(),pwd2:$("#pwd").val()},
success:function (data) {
//后台用JsonResponse返回数据
//data 就会被转成字典
console.log(data)
console.log(typeof data)
//JSON.parse(data) 把字符串类型转成字典
data=JSON.parse(data)
{#JSON.stringify()#}
console.log(typeof dat1)
if(data.status == 100){
//成功,跳转到指定页面
//location.href=地址,前端就会跳转到指定的url
alert(data.msg)
//$("#error").text(data.msg+'正在跳转')
//location.href=data.url
}else{
$("#error").text(data.msg)
} }
})
})

后端代码

def login(request):
dic={'status':100,'msg':None}
if request.method == 'GET':
return render(request, 'login.html')
# if request.is_ajax():
if request.method=='POST':
name=request.POST.get('name1')
pwd=request.POST.get('pwd2')
if name=='lqz' and pwd=='123':
dic['msg'] = '登陆成功'
# 想让前端跳转
# dic['url']='http://www.baidu.com'
dic['url']='/test/'
else:
# 返回json格式字符串
dic['status']=101
dic['msg']='用户名或密码错误'
# return JsonResponse(dic)
return HttpResponse(json.dumps(dic))

Django内置的序列化数据方法

from django.core import serializers

def test(request):
book_list = Book.objects.all()
ret = serializers.serialize('json', book_list)
return HttpResponse(ret)

Django 系列博客(十四)的更多相关文章

  1. Django 系列博客(四)

    Django 系列博客(四) 前言 本篇博客介绍 django 如何和数据库进行交互并且通过 model 进行数据的增删查改 ORM简介 ORM全称是:Object Relational Mappin ...

  2. Django 系列博客(十六)

    Django 系列博客(十六) 前言 本篇博客介绍 Django 的 forms 组件. 基本属性介绍 创建 forms 类时,主要涉及到字段和插件,字段用于对用户请求数据的验证,插件用于自动生成 h ...

  3. Django 系列博客(十二)

    Django 系列博客(十二) 前言 本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询. 聚合查询 语法:aggregate(*args, **kwargs) ...

  4. Django 系列博客(十)

    Django 系列博客(十) 前言 本篇博客介绍在 Django 中如何对数据库进行增删查改,主要为对单表进行操作. ORM简介 查询数据层次图解:如果操作 mysql,ORM 是在 pymysql ...

  5. Django 系列博客(一)

    Django 系列博客(一) 前言 学习了 python 这么久,终于到了Django 框架.这可以说是 python 名气最大的web 框架了,那么从今天开始会开始从 Django框架的安装到使用一 ...

  6. Django搭建博客网站(四)

    Django搭建博客网站(四) 最后一篇主要讲讲在后台文章编辑加入markdown,已经在文章详情页对markdown的解析. Django搭建博客网站(一) Django搭建博客网站(二) Djan ...

  7. Django 系列博客(十三)

    Django 系列博客(十三) 前言 本篇博客介绍 Django 中的常用字段和参数. ORM 字段 AutoField int 自增列,必须填入参数 primary_key=True.当 model ...

  8. Django 系列博客(十一)

    Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...

  9. Django 系列博客(九)

    Django 系列博客(九) 前言 本篇博客介绍 Django 模板的导入与继承以及导入导入静态文件的几种方式. 模板导入 模板导入 语法:``{% include '模板名称' %} 如下: < ...

随机推荐

  1. java 新手指南

    Java新手指南 不小心走上了一条不归路的我 因为对可视化感兴趣,然后学了MFC,发现MFC好麻烦啊,不如开发APP吧,刚学开发APP,艹,居然是用java做开发,那只好学java了,,呜呜,不知道什 ...

  2. 在 Vim 中优雅地查找和替换(转)

    总有人问我 Vim 中能不能查找,当然能!而且是超级强的查找! 这篇文章来详细介绍 Vim 中查找相关的设置和使用方法. 包括查找与替换.查找光标所在词.高亮前景/背景色.切换高亮状态.大小写敏感查找 ...

  3. Tomcat问题

    1 Tomcat控制台中文乱码 打开tomcat/conf/logging.properties 找到java.util.logging.ConsoleHandler.encoding = UTF-8 ...

  4. 【转载】.NET压缩/解压文件/夹组件

    转自:http://www.cnblogs.com/asxinyu/archive/2013/03/05/2943696.html 阅读目录 1.前言 2.关于压缩格式和算法的基础 3.几种常见的.N ...

  5. three.js的wave特效(ivew官网首页波浪特效实现)

    查看效果请访问:https://521lbx.github.io/Web3D/index.html公司的好几个vue项目都是用ivew作为UI框架,所以ivew官网时不时就得逛一圈.每一次进首页都会被 ...

  6. LinkedBlockingQueue 注记

    近期看一个音频传输代码时,对方采用了LinkedBlockingQueue为生产者.消费者模式,来支撑读写线程. 个人感觉非常不错,因此也对这种方式进行总结,并梳理了一个基本的功能框架备用.主要两点: ...

  7. Vue 学习笔记 — filter

    简书 对将要插入html的对象进行处理 一个简单的Vue示例 基本过滤器用法 带参数的过滤器 全局过滤器 (这张图片有点问题,最后显示的应该是 hello world不是null) 过滤器的简单应用 ...

  8. 从零开始学深度学习mxnet教程:安装以及基本操作

    一.导言 本教程适合对人工智能有一定的了解的同学,特别是对实际使⽤深度学习感兴趣的⼤学⽣.⼯程师和研究⼈员.但本教程并不要求你有任何深度学习或者机器学习的背景知识,我们将从头开始解释每⼀个概念.虽然深 ...

  9. Tomcat优化详解

    1          概述         本文档主要介绍了Tomcat的性能调优的原理和方法.可作为公司技术人员为客户Tomcat系统调优的技术指南,也可以提供给客户的技术人员作为他们性能调优的指导 ...

  10. 1 小时 SQL 极速入门(二)

    上篇我们说了 SQL 的基本语法,掌握了这些基本语法后,我们可以对单表进行查询及计算分析.但是一个大的系统,往往会有数十上百张表,而业务关系又错综复杂.我们要查的数据往往在好几张表中,而要从多张表中来 ...