django 之 Ajax and so on
MTV与MVC(了解)
MTV模型(django):
- M:模型层(models.py)
T:templates
V:views
MVC模型:
- M:模型层(models.py)
V:视图层(views.py)
C:控制器(Controller) urls.py- 本质:django的MTV也是MVC
多对多表三种创建方式
1.第一种 django orm自动帮我们创建
models.py 模型表
- 1 from django.db import models
- 2
- 3 Create your models here.
- 4 # 第一种创建方式:
- 5 class Book(models.Model):
- 6 name = models.CharField(max_length=32)
- 7 authors = models.ManyToManyField(to='Author') 多对多的关系,Book与Author之间的绑定
- 8
- 9 class Author(models.Model):
- 10 name = models.CharField(max_length=32)
结论:django orm 自动帮我们创建的第三张表是不可以对第三张表进行操作,如增加字段
2.第二种纯手动创建第三张表
models.py 模型表
- from django.db import models
- Create your models here.
- class Book(models.Model):
- name = models.CharField(max_length=32)
- class Author(models.Model):
- name = models.CharField(max_length=32)
- class Book2Author(models.Model):
- #foreignkey自动加_id
- book = models.ForeignKey(to='Book',on_delete=models.CASCADE)
- author = models.ForeignKey(to='Author',on_delete=models.CASCADE)
- #可以加字段,如果是jdango自动创建第三张表就不可以
- info = models.CharField(max_length=32)
test.py 测试文件
- 1 import os
- 2 import sys
- 3
- 4 if __name__ == '__main__':
- 5 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day60.settings')
- 6 import django
- 7 django.setup()
- 8 from app01 import models
- 9
- 10 # 查询书籍对应的作者
- 11 # 正向
- 12 res = models.Book.objects.filter(pk=1).values('author__name')
- 13 print(res)
- 14 # 报错信息(手动创建不支持orm方式取值)
- 15 # django.core.exceptions.FieldError: Cannot resolve keyword 'author' into field. Choices are: book2author, id, name
- 16 # 反向
- 17 book_obj = models.Book.objects.filter(pk=1).first()
- 18 res= book_obj.author_set
- 19 print(res)
- 20 # 报错信息(不支持)
- 21 # django.core.exceptions.FieldError: Cannot resolve keyword 'author' into field. Choices are: book2author, id, name
结论:纯手动创建多对多关系第三张表,可以增加字段,但是不符合ORM查询!!!
3.第三种半自动创建第三张表
models.py 模型表
- 1 from django.db import models
- 2
- 3 Create your models here.
- 4
- 5 class Book(models.Model):
- 6 name = models.CharField(max_length=32)
- 7 #through='Book2Author' 告诉diango我自己创建了第三张表,你不用帮我创建了
- 8 #through_fields=(('(字母小写)通过哪个参数可以查到我这张表','(字母小写)需要查询字段的表'))
- 9 #虚拟字段,数据库看不到
- 10 authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
- 11
- 12
- 13 class Author(models.Model):
- 14 name = models.CharField(max_length=32)
- 15 # 也可以在这里关联
- 16 # books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))
- 17
- 18 class Book2Author(models.Model):
- 19 #foreignkey自动加_id
- 20 book = models.ForeignKey(to='Book',on_delete=models.CASCADE)
- 21 author = models.ForeignKey(to='Author',on_delete=models.CASCADE)
- 22 #可以加字段,如果是jdango自动创建第三张表就不可以
- 23 info = models.CharField(max_length=32)
test.py 测试文件
- 1 import os
- 2 import sys
- 3
- 4 if __name__ == '__main__':
- 5 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day60.settings')
- 6 import django
- 7 django.setup()
- 8 from app01 import models
- 9
- 10
- 11 #正向查
- 12 book = models.Book.objects.filter(pk=1).values('authors__name')
- 13 print(book)
- 14 book_obj = models.Book.objects.filter(pk=1).first()
- 15 res1 = book_obj.authors.all()
- 16 print(res1)
- 17 #反向查询
- 18 res = models.Author.objects.filter(pk=1).values('book__name')
- 19 print(res)
- 20 res2 = models.Author.objects.filter(pk=1).values('book2author__info')
- 21 print(res2)
- 22
- 23
- 24 # 结果:
- 25 # < QuerySet[{'authors__name': 'yaya'}] >
- 26 # < QuerySet[ < Author: Author object(1) >] >
- 27 # < QuerySet[{'book__name': '书名'}] >
- 28 # < QuerySet[{'book2author__info': 'hahah'}] >
结论:可扩展性高,可以增加字段,并且符合ORM查询方式
前后端传输数据编码格式contentType
urlencoded
index.html 前端文件
- 1 <!DOCTYPE html>
- 2 <html lang="en">
- 3 <head>
- 4 <meta charset="UTF-8">
- 5 <title>Title</title>
- 6 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
- 7
- 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
- 9 <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
- 10
- 11 <link href="https://cdn.bootcss.com/font-awesome/5.8.2/css/fontawesome.min.css" rel="stylesheet">
- 12 <script src="https://cdn.bootcss.com/font-awesome/5.8.2/js/fontawesome.min.js"></script>
- 13
- 14 <link href="https://cdn.bootcss.com/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
- 15 <script src="https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"></script>
- 16 </head>
- 17 <body>
- 18 <form action="" method="post" >
- 19 <input type="text" name="name">
- 20 <input type="text" name="password">
- 21
- 22 <input type="submit">
- 23 </form>
- 24 </body>
- 25 </html>
views.py 视图函数文件
- from django.shortcuts import render,HttpResponse,redirect
- def index(request):
- print(request.POST)
- return render(request,'index.html',locals())
结论:urlencoded
- 对应的数据格式:name=egon&password=123
- 后端获取的数据:request.POST
- ps:django会将urlencoded编码的数据解析自动放到request.POST里
formdata
index.html 前端页面
- 1 <!DOCTYPE html>
- 2 <html lang="en">
- 3 <head>
- 4 <meta charset="UTF-8">
- 5 <title>Title</title>
- 6 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
- 7
- 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
- 9 <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
- 10
- 11 <link href="https://cdn.bootcss.com/font-awesome/5.8.2/css/fontawesome.min.css" rel="stylesheet">
- 12 <script src="https://cdn.bootcss.com/font-awesome/5.8.2/js/fontawesome.min.js"></script>
- 13
- 14 <link href="https://cdn.bootcss.com/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
- 15 <script src="https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"></script>
- 16 </head>
- 17 <body>
- 18 <form action="" method="post" >
- 19
- 20 <input type="text" name="name">
- 21 <input type="text" name="password">
- 22 <input type="file" name="myfile">
- 23 <input type="submit">
- 24 </form>
views.py 视图函数文件
- 1 from django.shortcuts import render,HttpResponse,redirect
- 2 import json
- 3 # Create your views here.
- 4 from app01 import models
- 5 from app01.utils import my_page
- 6 # form 表单支持urlencoded和formdata这两种方式
- 7 def index(request):
- 8 print(request.POST)
- 9 # <QueryDict: {'name': ['egon'], 'password': ['123'], 'myfile': ['1.png']}>
- 10 # 'myfile': ['5.png']拿到的是文件的名字,并不是文件的内容
- 11 print(request.FILES)
- 12 # <MultiValueDict: {}> 为空
- 13 return render(request,'index.html',locals())
结论:form 表单默认的是urlencoed, 不能获取到文件的对象,就是文件的内容,所以我们在form表单中要指定
- enctype="multipart/form-data"
后端中request.FILES中获取文件的对象
- formdata
form表单传输文件的编码格式
后端获取文件格式数据:request.FILES
后端获取普通键值对数据:request.POST- 首先先声明一下:
- 前端有哪些方式可以朝后端发请求:
- 浏览器窗口手动输入网址(get请求)
a标签的href属性(get请求)
form表单(get/post请求(默认是get请求))
ajax(get/post请求)
ajax
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
特点:
1.局部刷新:AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)如:github的注册,名字重新会提醒。
2.异步提交:客户发出一个请求之后,无需等待服务器响应结束,就可以发出第二个请求。
ajax基本语法:
- 提交的地址(url)
提交的方式(type)
提交的数据(data)
回调函数(success)
- <script>
- $('#d1').click(function(){
$.ajax({
//提交的地址
url :'/index',
//提交的方式
type:'post',
//提交的数据
data:{'name':'jason','password':'123'},
//回调函数
success: function(data){ //data异步提交返回的结果
alert(data)
}
})- </script>
来个小例子趴
页面输入两个整数,通过AJAX传输到后端计算出结果并返回。
views.py
- 1 from django.shortcuts import render,HttpResponse,redirect
- 2 import json
- 3 Create your views here.
- 4 from app01 import models
- 5 from app01.utils import my_page
- 6
- 7 def index(request):
- 8 print(request.POST)
- 9 if request.method == 'POST':
- 10 i1 = request.POST.get('i1')
- 11 i2 = request.POST.get('i2')
- 12 # res=i1+i2 字符串
- 13 res = int(i1)+int(i2) 要转成整型才可以进行运算
- 14 print(res,type(res))
- 15 return HttpResponse(res)
- 16 return render(request, 'index.html', locals())
index.py
- 1 <input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
- 2 <button id="d1">加我加我~</button>
- 3 <script>
- 4 $('#d1').click(function(){
- 5 $.ajax({
- 6 url:'', //默认当前路径
- 7 type:'post', //post小写就好
- 8 data:{'i1':$('#i1').val(), 'i2':$('#i2').val()},
- 9 success:function(data){
- 10 $('#i3').val(data)
- 11 }
- 12 })
- 13 })
- 14 </script>
yaya对ajax的小理解:
前端的数据通过ajax方式提交给后端,然后会有一个返回的结果,前端并不需要等待结果,所以页面不刷新,可以继续输入,提交,页面都会显示你刚刚输入的数据(如果是form表单提交,提交页面会刷新,前端页面的数据就没有了),然后提交的数据结果是通过回调函数要回来进行展示的。
- ajax传输json数据:
index.html
- 1 <input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
- 2 <button id="d1">加我加我~</button>
- 3 <script>
- 4 $('#d1').click(function(){
- 5 $.ajax({
- 6 url:'', //默认当前路径
- 7 type:'post', //post小写就好
- 8 contentType:'application/json',
- 9 data :JSON.stringify({'name':'jason','hobby':'study'}),
- 10 success:function(data){
- 11 $('#i3').val(data)
- 12 }
- 13 })
- 14 })
- 15
- 16 </script>
views.py
- 1 def index(request):
- 2
- 3 if request.method == 'POST':
- 4 print(request.POST)
- 5 print(request.body) #byte字符串 body除了用ajax方式提交数据才可以查看,其他方式查看会报错
- 6 data= request.body
- 7 #第一种方式
- 8 res = data.decode('utf-8')
- 9 #第二种方式
- 10 # res2 = str(data,encoding='uyf-8')
- 11 # print(res2,type(res2))
- 12 res3 = json.loads(res)
- 13 print(res3, type(res3))
- 14
- 15 return HttpResponse('ok')
- 16 return render(request, 'index.html', locals())
注意:
1.ajax提交的方式默认是urlencoed,如果前端在传输数据的时候没有说明是json格式传输数据的(没有写这句话contentType:'application/json')就会以urlencoed的方式传输给后端,print(request.POST) 结果是 (以整个传输的字典数据当作是key,value是空)
2.ajax以json传输的数据不是在POST中(打印request.POST为空),而是在body里(打印request.body得到二进制数据),所以要进行解码
3.前后端传输数据,你不要骗人家,数据是什么格式就要告诉别人是什么格式,数据与编码一一对应
4.body除了用ajax方式提交数据才查看,其他方式查看会报错
5.解码方式有两种:❣❣
第一种方式res = data.decode('utf-8')
第二种方式res = str(data, encoding='utf-8')
- ajax基于formdata传输文件:
index,html
- 1 <input type="file" name="myfile" id="i1">
- 2 <button id="d1">加我加我~</button>
- 3
- 4 <script>
- 5 $('#d1').click(function() 点击id为d1的button按钮触发事件{
- 6 //ajax需要借助对象FormData
- 7 let formdata = new FormData();
- 8 //FormData 不仅可以传文件还可以传普通的键值对
- 9 formdata.append('name','jason');
- 10 //如何获取input存放的文件
- 11 $('#i1')[0] //jquery转原生js对象,js对象中有files的方法,然后从files[0]列表中取出文件对象
- 12 formdata.append('myfile',$('#i1')[0].files[0]);
- 13 $.ajax({
- 14 url:'', //默认当前路径
- 15 type:'post', //post小写就好
- 16 contentType:formdata,//django能够自动识别该formdata对象,
- 17 // 不要用任何编码,用我自带的formdata自带的编码格式
- 18 data :formdata,
- 19 //发送文件需要修改两个固定的参数
- 20 processData:false, //告诉浏览器不要处理我的数据
- 21
- 22 success:function(data){不要用任何的编码,就用我formdata自带的编码格式,django能够自动识别改formdata对象
- 23 alert('收到了,老弟')
- 24 }
- 25 })
- 26 })
- 27
- 28 </script>
views.py
- 1 def index(request):
- 2 if request.method == 'POST':
- 3 print(request.POST)
- 4 print(request.FILES)
- 5
- 6 return HttpResponse('ok')
- 7 return render(request, 'index.html', locals())
结论:
- $('button标签的id').click(function () {
let (FormData产生的对象变量名接收) = new FormData();
// FormData对象不仅仅可以传文件还可以传普通的键值对
(FormData产生的对象变量名).append('字典的key','字典的value');
// 获取input框存放的文件
//$('input的标签id')[0].files[0]
(FormData产生的对象变量名).append('自定义文件名',$('input的标签id')[0].files[0]);
$.ajax({
url:'',
type:'post',
data:formdata,
// ajax发送文件需要修改两个固定的参数
processData:false, // 告诉浏览器不要处理我的数据
contentType:false, // 不要用任何的编码,就用我formdata自带的编码格式,django能够自动识别改formdata对象
// 回调函数
success:function (后端返回的结果,变量名来接收) {
alert(后端返回的结果,变量名来接收)
}
})
});
form表单与ajax异同点
- 1.form表单不支持异步提交局部刷新
2.form表单不支持传输json格式数据
3.form表单与ajax默认传输数据的编码格式都是urlencoded
批量插入数据
- 1 <!DOCTYPE html>
- 2 <html lang="en">
- 3 <head>
- 4 <meta charset="UTF-8">
- 5 <title>Title</title>
- 6 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
- 7
- 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
- 9 <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
- 10
- 11 <link href="https://cdn.bootcss.com/font-awesome/5.8.2/css/fontawesome.min.css" rel="stylesheet">
- 12 <script src="https://cdn.bootcss.com/font-awesome/5.8.2/js/fontawesome.min.js"></script>
- 13
- 14 <link href="https://cdn.bootcss.com/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
- 15 <script src="https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"></script>
- 16 </head>
- 17 <body>
- 18 <div class="container">
- 19 <div class="row">
- 20 <div class="col-md-8 col-md-offset-2">
- 21 <table class="table table-hover table-striped table-bordered">
- 22 <thead>
- 23 <tr>
- 24 <th>id</th>
- 25 <th>name</th>
- 26 </tr>
- 27 </thead>
- 28 <tbody>
- 29 {% for book_obj in book_list %}
- 30 <tr>
- 31 <td>{{ book_obj.pk }}</td>
- 32 <td>{{ book_obj.name }}</td>
- 33 </tr>
- 34 </tbody>
- 35 {% endfor %}
- 36 </table>
- 37 </div>
- 38 </div>
- 39 </div>
- 40 </body>
- 41 </html>
booklist.html
- 1 def booklist(request):
- 2 #动态插入100条数据
- 3 for i in range(100):
- 4 models.Book2.objects.create(name='第%s本书' %i)
- 5 # 查询所有的书籍展示到前端页面
- 6 bool_list = models.Book2.objects.all()
- 7 return render(request, 'booklist.html',locals())
views.py
以上是没有使用
- models.表名.objects.bulk_create(列表) 没有使用所以网速刷新很慢
- 1 def booklist(request):
- 2 #动态插入100000条数据 批量操作
- 3 l=[]
- 4 for i in range(10000):
- 5 l.append(models.Book2(name='第%s本书' %i))
- 6 #批量操作(插入的数据多并且速度快)
- 7 models.Book2.objects.bulk_create(l)
- 8 # 查询所有的书籍展示到前端页面
- 9 book_list = models.Book2.objects.all()
- 10 return render(request, 'booklist.html',locals())
自定义分页器
思路:
- 1. book_list = models.Book2.objects.all()[0:10]
all()获取到Book2表中所有的书籍,列表套对象。然后列表可以切片索引(顾头不顾尾),这里是将书籍从索引为0的书籍作为第一个取出一直到索引为10的书籍展示在一个页面上;
- 2.每页展示10条数据
per_page_num = 10
当前页(current_page) | 起始位置(page_start) | 终止位置(page_end) |
1 | 0 | 10 |
2 | 10 | 20 |
3 | 20 | 30 |
- page_start = (current_page-1)*per_page_num
page_end = current_page*per_page_num
- book_list = models.Book2.objects.all()[page_start:page_end
- 不管第1,第2,第3还是切换其他的当前页都可以显示对应的书籍序列,以上就推出了代码实现的变动。
3.获取到访问的当前页crrent_page=request.get('page',1) 用户不传默认展示第一页
current_page=int(current_page) 得到的是字符串,所以要转成整型,才成进行运算
- 在前端需要访问url的时候还需要携带手动的输入当前页(不合理)
4.然后再引用bootstrap的分页器,再为一个页面的a标签加上携带curent_page的参数,在用户点击的时候可以跳转相应的页面,但是缺陷是我这个页面只能显示固定的当前页数
5.如果是100条数据,一页显示10条,需要显示10页,如果是101条,需要显示11页,用代码如何实现呢?
所以就用到了divmod
- 获取到数据的总条数:all_count = models.Book2.objects.all().count()
获取到总页数:pager_nums,more=divmod(all_count,per_page_num)
6.页码的渲染通常是单数1,3,5,7,9符合中国人的审美标准
- 7.由于需要循环拿出每一个当前页,但是前端没有range方法,所以只能到后端实现了之后再传给前端
- pager_nums,more = divmod(all_count,per_page_num)
if more:
pager_nums += 1- html = ''
for i in range(1,pager_nums+1):
html += '<li><a href="?page=%s">%s</a></li>'%(i,i)
- 8.前端需要写{{page_obj.page_html|safe}} #safe将后端传入的html语法数据进行展示
自定义分页器的使用
- 1 from django.db import models
- 2
- 3 Create your models here.
- 4
- 5 class Book2(models.Model):
- 6 name = models.CharField(max_length=32)
在app01下自创的utils文件夹,导入第三方文件
- 1 class Pagination(object):
- 2 def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
- 3 """
- 4 封装分页相关数据
- 5 :param current_page: 当前页
- 6 :param all_count: 数据库中的数据总条数
- 7 :param per_page_num: 每页显示的数据条数
- 8 :param pager_count: 最多显示的页码个数
- 9
- 10 用法:
- 11 queryset = model.objects.all()
- 12 page_obj = Pagination(current_page,all_count)
- 13 page_data = queryset[page_obj.start:page_obj.end]
- 14 获取数据用page_data而不再使用原始的queryset
- 15 获取前端分页样式用page_obj.page_html
- 16 """
- 17 try:
- 18 current_page = int(current_page)
- 19 except Exception as e:
- 20 current_page = 1
- 21
- 22 if current_page < 1:
- 23 current_page = 1
- 24
- 25 self.current_page = current_page
- 26
- 27 self.all_count = all_count
- 28 self.per_page_num = per_page_num
- 29
- 30 # 总页码
- 31 all_pager, tmp = divmod(all_count, per_page_num)
- 32 if tmp:
- 33 all_pager += 1
- 34 self.all_pager = all_pager
- 35
- 36 self.pager_count = pager_count
- 37 self.pager_count_half = int((pager_count - 1) / 2)
- 38
- 39 @property
- 40 def start(self):
- 41 return (self.current_page - 1) * self.per_page_num
- 42
- 43 @property
- 44 def end(self):
- 45 return self.current_page * self.per_page_num
- 46
- 47 def page_html(self):
- 48 # 如果总页码 < 11个:
- 49 if self.all_pager <= self.pager_count:
- 50 pager_start = 1
- 51 pager_end = self.all_pager + 1
- 52 # 总页码 > 11
- 53 else:
- 54 # 当前页如果<=页面上最多显示11/2个页码
- 55 if self.current_page <= self.pager_count_half:
- 56 pager_start = 1
- 57 pager_end = self.pager_count + 1
- 58
- 59 # 当前页大于5
- 60 else:
- 61 # 页码翻到最后
- 62 if (self.current_page + self.pager_count_half) > self.all_pager:
- 63 pager_end = self.all_pager + 1
- 64 pager_start = self.all_pager - self.pager_count + 1
- 65 else:
- 66 pager_start = self.current_page - self.pager_count_half
- 67 pager_end = self.current_page + self.pager_count_half + 1
- 68
- 69 page_html_list = []
- 70 # 添加前面的nav和ul标签
- 71 page_html_list.append('''
- 72 <nav aria-label='Page navigation>'
- 73 <ul class='pagination'>
- 74 ''')
- 75 first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
- 76 page_html_list.append(first_page)
- 77
- 78 if self.current_page <= 1:
- 79 prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
- 80 else:
- 81 prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
- 82
- 83 page_html_list.append(prev_page)
- 84
- 85 for i in range(pager_start, pager_end):
- 86 if i == self.current_page:
- 87 temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
- 88 else:
- 89 temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
- 90 page_html_list.append(temp)
- 91
- 92 if self.current_page >= self.all_pager:
- 93 next_page = '<li class="disabled"><a href="#">下一页</a></li>'
- 94 else:
- 95 next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
- 96 page_html_list.append(next_page)
- 97
- 98 last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
- 99 page_html_list.append(last_page)
- 100 # 尾部添加标签
- 101 page_html_list.append('''
- 102 </nav>
- 103 </ul>
- 104 ''')
- 105 return ''.join(page_html_list)
my_page.py
- 1 from django.shortcuts import render,HttpResponse
- 2 from app01 import models
- 3 from app01.utils import my_page
- 4
- 5 def booklist(request):
- 6 book_list = models.Book2.objects.all()
- 7 all_count = book_list.count()
- 8 current_page = request.GET.get('page',1)
- 9 page_obj = my_page.Pagination(current_page=current_page,all_count=all_count)
- 10 page_queryset = book_list[page_obj.start:page_obj.end]
- 11 return render(request,'booklist.html',locals())
小总结:
- 自定义分页器
页码的渲染通常都是单数1,3,5,7,9,符号中国人的审美标准- 需要完善的
1.加首页和尾页
2.页码的个数应该是固定的- 自定义分页器的使用
后端:
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]- 前端:
{{ page_obj.page_html|safe }} # 帮你渲染的是带有bootstrap样式的分页器
django 之 Ajax and so on的更多相关文章
- python Django之Ajax
python Django之Ajax AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案. 异步 ...
- django 接受 ajax 传来的数组对象
django 接受 ajax 传来的数组对象 发送:ajax 通过 POST 方式传来一个数组 接收:django 接受方式 array = request.POST.getlist(‘key[]’) ...
- python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)
昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...
- Django使用AJAX调用自己写的API接口
Django使用AJAX调用自己写的API接口 *** 具体代码和数据已上传到github https://github.com/PythonerKK/eleme-api-by-django-rest ...
- Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件
一.Django与Ajax AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻 ...
- Django之Ajax提交
Ajax 提交数据,页面不刷新 Ajax要引入jQuery Django之Ajax提交 Js实现页面的跳转: location.href = "/url/" $ajax({ url ...
- Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数
Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...
- Django之AJAX传输JSON数据
目录 Django之AJAX传输JSON数据 AJAX 中 JSON 数据传输: django响应JSON类型数据: django 响应 JSON 类型数据: Django之AJAX传输JSON数据 ...
- Django之ajax(jquery)封装(包含 将 csrftoken 写入请求头方法)
由于支持问题,未使用 es6 语法 _ajax.js /** * 发起请求 * @param url 请求地址 * @param data 请求数据 { } json格式 * @param type ...
- Django学习——图书管理系统图书修改、orm常用和非常用字段(了解)、 orm字段参数(了解)、字段关系(了解)、手动创建第三张表、Meta元信息、原生SQL、Django与ajax(入门)
1 图书管理系统图书修改 1.1 views 修改图书获取id的两种方案 1 <input type="hidden" name="id" value=& ...
随机推荐
- 初识Flask框架
Flask简介: Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架. Flask 本身相当于一个内核,其 ...
- plsql-工具安装部署及使用配置
参考文档链接:https://blog.csdn.net/li66934791/article/details/83856225 简介: PL/SQL Developer是一个集成开发环境,专门开发面 ...
- java集合-set
#java集合-set Map用于存储key-value的映射,其中key的值是不能重复的.并且还需要正确的覆写equals方法和hashCode方法 如果我们只需要存储不重复的key,并不需要存储对 ...
- localstorage二次封装-模块模式
var db = function () { // 本地存储前缀,减少命名冲突 var prefix = 'ydb'; return { setPrefix: function (_prefix) { ...
- DIV的失去焦点(blur)实现
用防抖实现DIV鼠标移出消失 由于div标签本身不支持onblur事件,所以对于点击一个按钮弹出的div,我们想要当这个div失去焦点的时候,让它消失不能使用的onblur来实现. 但是可以利用 ...
- html+css布局类型
一.单列布局 1.代码如下 <!doctype html> <html> <head> <meta charset="utf-8"/> ...
- PC端如何下载B站里面的视频?
此随笔只是记录一下: PC端下载B站的视频,在blibli前面加上一个i 然后在视频上鼠标右键,视频另存为+路径即可 PS:网上其他的方法,比如在blibli前面加上kan,后面加上jj等,这些方 ...
- Python 获取MySql某个表所有字段名
在使用python导出数据库中数据的时候,往往除了插入的数据以外,还有表字段等信息需要导出,查阅了资料后发现了2种方法 第一种:在mysql自带的表里查询,这个表保存了每张表的字段信息,可以用pymy ...
- 一起学习vue源码 - Object的变化侦测
作者:小土豆biubiubiu 博客园:www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d 简书:h ...
- Linux系统是什么?亲身自学经历分享
我是数字媒体专业学生,第一次接触LINUX的时候,是大一C语言课程里看到的,书上讲了C语言的发展历史.说到C语言的起源,就离不开UNIX系统.在20世纪60年代,贝尔实验室的研究员Ken Thomps ...