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 自带的分页器,和我们差不多,就相当于每次手动写一遍

又是一个愉快的周末

最新文章

  1. Openfire/XMPP学习之——一个简单的Smack样例
  2. length属性,length()方法和size()的方法的区别
  3. DataGrid获取当前行某列值
  4. 如何用JS判断推广链接所属的客服
  5. NYOJ之素数求和问题
  6. ios 开发中出现的 pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug
  7. Java常用类之Properties类
  8. Java Final, Finally, Finalize
  9. (LeetCode 135) Candy N个孩子站成一排,给每个人设定一个权重
  10. No application &#39;meetme&#39; for extension 错误
  11. android复习-AnsyTask
  12. 最新合购网源码net.asp程序 彩票合买功能采用全新内核、全新架构,更小巧、功能更强、更快、更安全稳定
  13. koa2 controller中实现类似sleep的延迟功能
  14. 开源项目 easydownload
  15. Centos扩容swap分区
  16. swift 实践- 04 -- UIButton
  17. 阿里云3台机器组成集群配置ssh免密码登陆
  18. python爬虫----XPath
  19. 旧题新做:从idy的视角看数据结构
  20. js文件命名冲突理解

热门文章

  1. Autotestplat体验中心
  2. Intellij IDEA创建 Web 项目
  3. scss入门学习(一)
  4. Redis(2)——跳跃表
  5. C++扬帆远航——12(抓小偷)
  6. 微信小程序学习简介
  7. idea 2018.1激活方法
  8. linux-TFTP服务
  9. LoadRunner 11破解方法:
  10. Java集合03——你不得不了解的Map