MTV与MVC模型

MTV与MVC都是模型,只不过MTV是django自己定义的,具体看一下他们的意思

MTV模型(django)

M:模型层(models.py)

T:templates文件夹

V:视图层(views)

MVC模型

M:模型层

V:视图层(views.py)

C:控制器(Controller) urls.py

总结:本质上django的MTV也是MVC

前后端传输数据编码格式

首先,在我们不指定传输数据的时候,默认的contentType都是urlencoded

urlencoded

  对应的数据格式:name=jason&password=555

  后端获取数据:request.POST  

  PS:django会将urlencded编码的数据解析自动放到request.POST

formdata

  form表单传输文件的编码格式

  后端获取文件格式数据:request.FILES

  后端获取普通键值对数据:request.POST

application/json

  form表单不支持,Ajax支持

  Ajax发送json格式数据

  需要注意的点

    编码与数据格式要一致

Ajax(重点掌握)

Ajax支持异步提交数据,局部刷新页面,这种情况我们在好多页面都会看到,那我们要如何做到呢?先来学习Ajax的基础语法~~~记住四兄弟即可

提交的地址(url):控制数据的提交地址,不写默认往当前位置提交

提交的方式(type):默认是get,要将get请求换成post

提交的数据(data):类似于字典的格式,字典具有一一标识的优点

回调函数(success):function(data){}data接收到的后端传输的数据

基本结构如下:

<script>  //记得写在html页面的最下方或者是你写在js里面,然后引入
$('绑定事件的id').click(function () { //给你要让Ajax触发的按钮绑定一个事件
$.ajax({ //Ajax的固定写法,在{}里面写你的四兄弟
url:'在这里写你的提交的路径', //不写默认是当前页面提交
type:'post' , //将请求方式从默认的get改成post
data:{}, //这个固定是data,后面放的是字典的形式
success:function (data) { //回调函数,拿到的是提交过后的数据,就是后端处理过后的数据,不要忘记参数,这个参数就是接收后端处理过后的数据
//对接受到的数据进行处理,做的是局部刷新操作
          alert(123)
}
})
})
</script>

自己尝试着写一个不跳转的动态页面,比如1+1=2

Ajax实现简单版页面局部刷新

我们首先需要的就是自己定义三个input框,然后动态获取到前两个框中的值,通过Ajax放到第三个input框中,代码演示如下

<input type="text" id="i1" >+<input type="text" id="i2" >=<input type="text" id="i3">
<button id="b1">点我点我</button> <script>
$('#b1').click(function () {
$.ajax({
url:'/index/',
type:'post',
data:{'i1':$('#i1').val(),'i2':$('#i2').val()},
success:function (data) { $('#i3').val(data) }
})
})
</script>

html展示

后端数据处理

def index(request):
if request.method=='POST':
i1=request.POST.get('i1')
i2=request.POST.get('i2')
print(i1,i2)
res=int(i1)+int(i2)
print(res,type(res))
return HttpResponse(res)
return render(request,'index.html')

views展示

注意:Ajax不要与form表单联合使用,直接使用input框就可以

Ajax实现json格式数据的传输

具体代码展示如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<p>username:<input type="text" id="u1"></p>
<p>password:<input type="password" id="p1"></p>
<button id="b1">提交</button>
<input type="text" id="i1"> <script>
$('#b1').click(function () {
$.ajax({
url:'',
type:'post',
contentType:'application/json',
data:JSON.stringify({
'username':$('#u1').val(),
'password':$('#p1').val()
}),
success:function (data) {
$('#i1').val(data) }
})
})
</script> </body>
</html>

json格式html展示

def jsonajax(request):
print('method:', request.method)
print('POST:', request.POST)
print('GET:', request.GET)
print('body:', request.body)
if request.method=='POST':
data=request.body
import json
res=data.decode('utf-8')
print(res,type(res))
res1=json.loads(res)
print(res1,type(res1))
return HttpResponse(res1)
return render(request,'jsonajax.html')

views展示

Ajax实现文件上传

  1.利用一个js内置对象FormData

  2.这个FormData即可以传普通的键值对也可以传文件

  3.需要修改两个默认的参数processData,contentType

  4.获取input框存储的文件数据$('input')[0].files[0]

def fileupload(request):

    if request.method=='POST':
print(request.POST)
print(request.FILES) return HttpResponse('收到了,小老弟')
return render(request,'fileupload.html')

Ajax实现文件上传views展示

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
文件上传:<input type="file" id="i1">
<button id="b1">点击提交</button>
<script>
$('#b1').click(function () {
//传文件的时候在form表单中我们需要制定参数是formdata,在这里我们也要来一个formdata
let formdata = new FormData();
// formData对象不仅可以传文件而且可以传普通的键值对
formdata.append('name','jason');
//获取input框存放的文件
//这里就用到了files这个方法,jquery是没有这个方法的,所以我们要先得到一个js对象
//$('#i1')[0].files[0] 是因为files里面有好多个文件,而我们只要第一个
formdata.append('myfile',$('#i1')[0].files[0]);
$.ajax({
url:'',
type:'post',
data:formdata,
//ajax发送文件需要修改两个固定的参数
processData:false, //告诉浏览器不要对数据进行处理
contentType:false, //告诉浏览器使用自带的formdata格式,不要编码
//回调函数
success:function (data) {
alert(data)
} })
})
</script>
</body>
</html>

Ajax实现文件上传html展示

总结:Ajax的特点是异步提交数据,产生局部刷新的效果,默认提交数据的方式是get提交,所以我们需要修改里面的type类型,然后我们还可以自定义FormData对象,Ajax也支持基于这个对象的大文件上传。

Ajax和form表单的区别:

1.form表单不支持异步提交局部刷新

2.form表单不支持传输json格式数据

3.form表单与Ajax默认传输数据的编码格式都是urlencoded

小结:基于现在所学,前端向后端发请求的方式有如下几种

1.浏览器窗口手动输入网址     get请求

2.a标签的href属性                  get请求

3.form表单                              get/post请求

4.Ajax                                     get/post请求

其中,form表单和Ajax默认请求都是get

批量插入数据

当你打开一个页面的时候,想要直接插入100条数据到数据库,然后直接展示到前端页面上来,如何做到?那还不简单,我可以直接for循环100条数据,然后插入数据库,最后在从数据库中查出来展示,上代码!

def insernum(request):
#动态插入100条数据
for i in range(100):
models.Num.objects.create(name='第%s本书'%i)
#查询所有的书籍展示到前端
book_list = models.Num.objects.all()
return render(request,'num.html',locals())

但是,我们这样子做到话,效果真的超级超级的低,前端页面一直在等待我们数据的插入,虽然实现了数据的插入和展示,但是效率太低,那我们就得用到一个新的方法,我们先生成1000个数据对象,不走数据库,速度是很快的,然后将这1000个数据对象一次性插入,django支持我们这么做,用的是bulk_creat(),批量插入数据,见代码

def booklist(request):
l=[] #数据太大的话,能不能做成生成器,每次只有一点****
for i in range(10000):
l.append(models.Book2(name='第%s本书'%i)) 生成了一个对象
models.Book2.objects.bulk_create(l) 批量插入数据,速度超级快   
  g=(=models.Book2(name = '%s'%i)for i in range(100000000))***
  
  models.Book2.objects.bulk_create(l)

自定义分页器

首先我们要先导入一个类,这个类可以帮我们实现分页的功能,将这个导入的文件放在utils里面,在下面新建一个py文件,你得给人家一个家不是吗!

class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数 用法:
queryset = model.objects.all()
page_obj = Pagination(current_page,all_count)
page_data = queryset[page_obj.start:page_obj.end]
获取数据用page_data而不再使用原始的queryset
获取前端分页样式用page_obj.page_html
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1 if current_page < 1:
current_page = 1 self.current_page = current_page self.all_count = all_count
self.per_page_num = per_page_num # 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2) @property
def start(self):
return (self.current_page - 1) * self.per_page_num @property
def end(self):
return self.current_page * self.per_page_num def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1 # 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1 page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page) if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp) if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page) last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)

分页器

然后我们直接导入使用就可以了

    后端:
book_list = models.Book2.objects.all()
# 数据总条数
all_count = book_list.count()
# 当前页
current_page = request.GET.get('page',1)
# 实例一个分页器对象
page_obj = my_page.Pagination(current_page=current_page,all_count=all_count)
# 对总数据进行切片
page_queryset = book_list[page_obj.start:page_obj.end] 前端:
1.将book_list全部替换册灰姑娘book_queryset    
       2.渲染分页器样式
{{ page_obj.page_html|safe }} # 帮你渲染的是带有bootstrap样式的分页器

django 自带的分页器,和我们差不多,就相当于每次手动写一遍

又是一个愉快的周末

Django之Ajax传输数据的更多相关文章

  1. django使用ajax传输数据

    HTML文件ajax get例子 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  2. python Django之Ajax

    python Django之Ajax AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案. 异步 ...

  3. python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)

    昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...

  4. Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件

    一.Django与Ajax AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻 ...

  5. Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数

    Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...

  6. django 接受 ajax 传来的数组对象

    django 接受 ajax 传来的数组对象 发送:ajax 通过 POST 方式传来一个数组 接收:django 接受方式 array = request.POST.getlist(‘key[]’) ...

  7. Django使用AJAX调用自己写的API接口

    Django使用AJAX调用自己写的API接口 *** 具体代码和数据已上传到github https://github.com/PythonerKK/eleme-api-by-django-rest ...

  8. Django之Ajax提交

    Ajax 提交数据,页面不刷新 Ajax要引入jQuery Django之Ajax提交 Js实现页面的跳转: location.href = "/url/" $ajax({ url ...

  9. Django之AJAX传输JSON数据

    目录 Django之AJAX传输JSON数据 AJAX 中 JSON 数据传输: django响应JSON类型数据: django 响应 JSON 类型数据: Django之AJAX传输JSON数据 ...

随机推荐

  1. 360若真入股HTC 到底是谁来拯救谁

    到底是谁来拯救谁" title="360若真入股HTC 到底是谁来拯救谁"> 我总是持有一种观点,那就是拯救是相互的.就像老师拯救"堕落"学生, ...

  2. Hihocoder1456 Rikka with Lattice

    众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:勇太有一个$n times m$的点阵,他想要从这$n times m$个点中选出三个点 ${A,B,C}$,满足 ...

  3. Selenium 实现自动下载文件(FirefoxOptions,FirefoxProfile) - 根据Selenium Webdriver3实战宝典

    Firefox 版本是72geckodriver 是 0.24selenium 是3.14 代码中注释有关于FirefoxOptions,FirefoxProfile的解释,请各位寻找一下,不做另外解 ...

  4. python画一颗拳头大的💗

    用上turtle库后,各种画,今天画个拳头大的爱心@.@. 下面贴下代码: # -*- coding: utf-8 -*- # Nola import pygame import time impor ...

  5. 一起了解 .Net Foundation 项目 No.15

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. NUnit Test Fr ...

  6. A. New Building for SIS Codeforce

    You are looking at the floor plan of the Summer Informatics School's new building. You were tasked w ...

  7. 02 HDFS 分布式环境实战

    HDFS的主要设计理念 1.存储超大文件 这里的“超大文件”是指几百MB.GB甚至TB级别的文件. 2.最高效的访问模式是 一次写入.多次读取(流式数据访问)3.运行在普通廉价的服务器上 HDFS设计 ...

  8. 一起了解 .Net Foundation 项目 No.19

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Salesforce To ...

  9. 关于QThread使用锁死的探索

    在学习使用QT5的时候,发现要使用多线程处理多任务,按照https://www.cnblogs.com/liming19680104/p/10397052.html等很多网上的方法,测试一下,发现我写 ...

  10. 结题报告--hih0CoderP1041

    题目:点此 描述 小Hi和小Ho准备国庆期间去A国旅游.A国的城际交通比较有特色:它共有n座城市(编号1-n):城市之间恰好有n-1条公路相连,形成一个树形公路网.小Hi计划从A国首都(1号城市)出发 ...