MTV与MVC(了解)

MTV模型(django):

  1. M:模型层(models.py)
    T:templates
    V:views

MVC模型:

  1. M:模型层(models.py)
    V:视图层(views.py)
    C:控制器(Controller) urls.py
  2.  
  3. 本质:djangoMTV也是MVC

多对多表三种创建方式

1.第一种 django orm自动帮我们创建

models.py 模型表

  1. 1 from django.db import models
  2. 2
  3. 3 Create your models here.
  4. 4 # 第一种创建方式:
  5. 5 class Book(models.Model):
  6. 6 name = models.CharField(max_length=32)
  7. 7 authors = models.ManyToManyField(to='Author') 多对多的关系,BookAuthor之间的绑定
  8. 8
  9. 9 class Author(models.Model):
  10. 10 name = models.CharField(max_length=32)

结论:django orm 自动帮我们创建的第三张表是不可以对第三张表进行操作,如增加字段

2.第二种纯手动创建第三张表

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.  
  8. class Author(models.Model):
  9. name = models.CharField(max_length=32)
  10.  
  11. class Book2Author(models.Model):
  12. #foreignkey自动加_id
  13. book = models.ForeignKey(to='Book',on_delete=models.CASCADE)
  14. author = models.ForeignKey(to='Author',on_delete=models.CASCADE)
  15. #可以加字段,如果是jdango自动创建第三张表就不可以
  16. info = models.CharField(max_length=32)

test.py 测试文件

  1. 1 import os
  2. 2 import sys
  3. 3
  4. 4 if __name__ == '__main__':
  5. 5 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day60.settings')
  6. 6 import django
  7. 7 django.setup()
  8. 8 from app01 import models
  9. 9
  10. 10 # 查询书籍对应的作者
  11. 11 # 正向
  12. 12 res = models.Book.objects.filter(pk=1).values('author__name')
  13. 13 print(res)
  14. 14 # 报错信息(手动创建不支持orm方式取值)
  15. 15 # django.core.exceptions.FieldError: Cannot resolve keyword 'author' into field. Choices are: book2author, id, name
  16. 16 # 反向
  17. 17 book_obj = models.Book.objects.filter(pk=1).first()
  18. 18 res= book_obj.author_set
  19. 19 print(res)
  20. 20 # 报错信息(不支持)
  21. 21 # django.core.exceptions.FieldError: Cannot resolve keyword 'author' into field. Choices are: book2author, id, name

结论:纯手动创建多对多关系第三张表,可以增加字段,但是不符合ORM查询!!!

3.第三种半自动创建第三张表

models.py 模型表

  1. 1 from django.db import models
  2. 2
  3. 3 Create your models here.
  4. 4
  5. 5 class Book(models.Model):
  6. 6 name = models.CharField(max_length=32)
  7. 7 #through='Book2Author' 告诉diango我自己创建了第三张表,你不用帮我创建了
  8. 8 #through_fields=(('(字母小写)通过哪个参数可以查到我这张表','(字母小写)需要查询字段的表'))
  9. 9 #虚拟字段,数据库看不到
  10. 10 authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
  11. 11
  12. 12
  13. 13 class Author(models.Model):
  14. 14 name = models.CharField(max_length=32)
  15. 15 # 也可以在这里关联
  16. 16 # books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))
  17. 17
  18. 18 class Book2Author(models.Model):
  19. 19 #foreignkey自动加_id
  20. 20 book = models.ForeignKey(to='Book',on_delete=models.CASCADE)
  21. 21 author = models.ForeignKey(to='Author',on_delete=models.CASCADE)
  22. 22 #可以加字段,如果是jdango自动创建第三张表就不可以
  23. 23 info = models.CharField(max_length=32)

test.py 测试文件

  1. 1 import os
  2. 2 import sys
  3. 3
  4. 4 if __name__ == '__main__':
  5. 5 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day60.settings')
  6. 6 import django
  7. 7 django.setup()
  8. 8 from app01 import models
  9. 9
  10. 10
  11. 11 #正向查
  12. 12 book = models.Book.objects.filter(pk=1).values('authors__name')
  13. 13 print(book)
  14. 14 book_obj = models.Book.objects.filter(pk=1).first()
  15. 15 res1 = book_obj.authors.all()
  16. 16 print(res1)
  17. 17 #反向查询
  18. 18 res = models.Author.objects.filter(pk=1).values('book__name')
  19. 19 print(res)
  20. 20 res2 = models.Author.objects.filter(pk=1).values('book2author__info')
  21. 21 print(res2)
  22. 22
  23. 23
  24. 24 # 结果:
  25. 25 # < QuerySet[{'authors__name': 'yaya'}] >
  26. 26 # < QuerySet[ < Author: Author object(1) >] >
  27. 27 # < QuerySet[{'book__name': '书名'}] >
  28. 28 # < QuerySet[{'book2author__info': 'hahah'}] >

结论:可扩展性高,可以增加字段,并且符合ORM查询方式

前后端传输数据编码格式contentType

urlencoded

index.html 前端文件

  1. 1 <!DOCTYPE html>
  2. 2 <html lang="en">
  3. 3 <head>
  4. 4 <meta charset="UTF-8">
  5. 5 <title>Title</title>
  6. 6 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  7. 7
  8. 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  9. 9 <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
  10. 10
  11. 11 <link href="https://cdn.bootcss.com/font-awesome/5.8.2/css/fontawesome.min.css" rel="stylesheet">
  12. 12 <script src="https://cdn.bootcss.com/font-awesome/5.8.2/js/fontawesome.min.js"></script>
  13. 13
  14. 14 <link href="https://cdn.bootcss.com/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
  15. 15 <script src="https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"></script>
  16. 16 </head>
  17. 17 <body>
  18. 18 <form action="" method="post" >
  19. 19 <input type="text" name="name">
  20. 20 <input type="text" name="password">
  21. 21
  22. 22 <input type="submit">
  23. 23 </form>
  24. 24 </body>
  25. 25 </html>

views.py 视图函数文件

  1. from django.shortcuts import render,HttpResponse,redirect
  2.  
  3. def index(request):
  4. print(request.POST)
  5. return render(request,'index.html',locals())

结论:urlencoded

  • 对应的数据格式:name=egon&password=123
  • 后端获取的数据:request.POST
  • ps:django会将urlencoded编码的数据解析自动放到request.POST里

formdata

index.html 前端页面

  1. 1 <!DOCTYPE html>
  2. 2 <html lang="en">
  3. 3 <head>
  4. 4 <meta charset="UTF-8">
  5. 5 <title>Title</title>
  6. 6 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  7. 7
  8. 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  9. 9 <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
  10. 10
  11. 11 <link href="https://cdn.bootcss.com/font-awesome/5.8.2/css/fontawesome.min.css" rel="stylesheet">
  12. 12 <script src="https://cdn.bootcss.com/font-awesome/5.8.2/js/fontawesome.min.js"></script>
  13. 13
  14. 14 <link href="https://cdn.bootcss.com/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
  15. 15 <script src="https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"></script>
  16. 16 </head>
  17. 17 <body>
  18. 18 <form action="" method="post" >
  19. 19
  20. 20 <input type="text" name="name">
  21. 21 <input type="text" name="password">
  22. 22 <input type="file" name="myfile">
  23. 23 <input type="submit">
  24. 24 </form>

views.py 视图函数文件

  1. 1 from django.shortcuts import render,HttpResponse,redirect
  2. 2 import json
  3. 3 # Create your views here.
  4. 4 from app01 import models
  5. 5 from app01.utils import my_page
  6. 6 # form 表单支持urlencoded和formdata这两种方式
  7. 7 def index(request):
  8. 8 print(request.POST)
  9. 9 # <QueryDict: {'name': ['egon'], 'password': ['123'], 'myfile': ['1.png']}>
  10. 10 # 'myfile': ['5.png']拿到的是文件的名字,并不是文件的内容
  11. 11 print(request.FILES)
  12. 12 # <MultiValueDict: {}> 为空
  13. 13 return render(request,'index.html',locals())

结论:form 表单默认的是urlencoed, 不能获取到文件的对象,就是文件的内容,所以我们在form表单中要指定

  1. enctype="multipart/form-data"
    后端中request.FILES中获取文件的对象
  1. formdata
    form表单传输文件的编码格式
    后端获取文件格式数据:request.FILES
    后端获取普通键值对数据:request.POST
  2.  
  3. 首先先声明一下:
  1. 前端有哪些方式可以朝后端发请求:
  1. 浏览器窗口手动输入网址(get请求)
    a标签的href属性(get请求)
    form表单(get/post请求(默认是get请求))
    ajaxget/post请求)

ajax

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

特点

1.局部刷新:AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)如:github的注册,名字重新会提醒。

2.异步提交:客户发出一个请求之后,无需等待服务器响应结束,就可以发出第二个请求。

ajax基本语法

  1. 提交的地址(url)
    提交的方式(type)
    提交的数据(data)
    回调函数(success)
  1. <script>
  2.  
  3. $('#d1').click(function(){
    $.ajax({
    //提交的地址
    url :'/index',
    //提交的方式
    type:'post',
    //提交的数据
    data:{'name':'jason','password':'123'},
    //回调函数
    success: function(data){ //data异步提交返回的结果
    alert(data)
    }
    })
  4.  
  5. </script>
    来个小例子趴
    页面输入两个整数,通过AJAX传输到后端计算出结果并返回。
    views.py
  1. 1 from django.shortcuts import render,HttpResponse,redirect
  2. 2 import json
  3. 3 Create your views here.
  4. 4 from app01 import models
  5. 5 from app01.utils import my_page
  6. 6
  7. 7 def index(request):
  8. 8 print(request.POST)
  9. 9 if request.method == 'POST':
  10. 10 i1 = request.POST.get('i1')
  11. 11 i2 = request.POST.get('i2')
  12. 12 # res=i1+i2 字符串
  13. 13 res = int(i1)+int(i2) 要转成整型才可以进行运算
  14. 14 print(res,type(res))
  15. 15 return HttpResponse(res)
  16. 16 return render(request, 'index.html', locals())

index.py

  1. 1 <input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
  2. 2 <button id="d1">加我加我~</button>
  3. 3 <script>
  4. 4 $('#d1').click(function(){
  5. 5 $.ajax({
  6. 6 url:'', //默认当前路径
  7. 7 type:'post', //post小写就好
  8. 8 data:{'i1':$('#i1').val(), 'i2':$('#i2').val()},
  9. 9 success:function(data){
  10. 10 $('#i3').val(data)
  11. 11 }
  12. 12 })
  13. 13 })
  14. 14 </script>

yaya对ajax的小理解:

前端的数据通过ajax方式提交给后端,然后会有一个返回的结果,前端并不需要等待结果,所以页面不刷新,可以继续输入,提交,页面都会显示你刚刚输入的数据(如果是form表单提交,提交页面会刷新,前端页面的数据就没有了),然后提交的数据结果是通过回调函数要回来进行展示的。

  • ajax传输json数据

index.html

  1. 1 <input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
  2. 2 <button id="d1">加我加我~</button>
  3. 3 <script>
  4. 4 $('#d1').click(function(){
  5. 5 $.ajax({
  6. 6 url:'', //默认当前路径
  7. 7 type:'post', //post小写就好
  8. 8 contentType:'application/json',
  9. 9 data :JSON.stringify({'name':'jason','hobby':'study'}),
  10. 10 success:function(data){
  11. 11 $('#i3').val(data)
  12. 12 }
  13. 13 })
  14. 14 })
  15. 15
  16. 16 </script>

views.py

  1. 1 def index(request):
  2. 2
  3. 3 if request.method == 'POST':
  4. 4 print(request.POST)
  5. 5 print(request.body) #byte字符串 body除了用ajax方式提交数据才可以查看,其他方式查看会报错
  6. 6 data= request.body
  7. 7 #第一种方式
  8. 8 res = data.decode('utf-8')
  9. 9 #第二种方式
  10. 10 # res2 = str(data,encoding='uyf-8')
  11. 11 # print(res2,type(res2))
  12. 12 res3 = json.loads(res)
  13. 13 print(res3, type(res3))
  14. 14
  15. 15 return HttpResponse('ok')
  16. 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. 1 <input type="file" name="myfile" id="i1">
  2. 2 <button id="d1">加我加我~</button>
  3. 3
  4. 4 <script>
  5. 5 $('#d1').click(function() 点击idd1button按钮触发事件{
  6. 6 //ajax需要借助对象FormData
  7. 7 let formdata = new FormData();
  8. 8 //FormData 不仅可以传文件还可以传普通的键值对
  9. 9 formdata.append('name','jason');
  10. 10 //如何获取input存放的文件
  11. 11 $('#i1')[0] //jquery转原生js对象,js对象中有files的方法,然后从files[0]列表中取出文件对象
  12. 12 formdata.append('myfile',$('#i1')[0].files[0]);
  13. 13 $.ajax({
  14. 14 url:'', //默认当前路径
  15. 15 type:'post', //post小写就好
  16. 16 contentType:formdata,//django能够自动识别该formdata对象,
  17. 17 // 不要用任何编码,用我自带的formdata自带的编码格式
  18. 18 data :formdata,
  19. 19 //发送文件需要修改两个固定的参数
  20. 20 processData:false, //告诉浏览器不要处理我的数据
  21. 21
  22. 22 success:function(data){不要用任何的编码,就用我formdata自带的编码格式,django能够自动识别改formdata对象
  23. 23 alert('收到了,老弟')
  24. 24 }
  25. 25 })
  26. 26 })
  27. 27
  28. 28 </script>

views.py

  1. 1 def index(request):
  2. 2 if request.method == 'POST':
  3. 3 print(request.POST)
  4. 4 print(request.FILES)
  5. 5
  6. 6 return HttpResponse('ok')
  7. 7 return render(request, 'index.html', locals())

结论:

  1. $('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. 1.form表单不支持异步提交局部刷新
    2.form表单不支持传输json格式数据
    3.form表单与ajax默认传输数据的编码格式都是urlencoded

批量插入数据

  1. 1 <!DOCTYPE html>
  2. 2 <html lang="en">
  3. 3 <head>
  4. 4 <meta charset="UTF-8">
  5. 5 <title>Title</title>
  6. 6 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  7. 7
  8. 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  9. 9 <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
  10. 10
  11. 11 <link href="https://cdn.bootcss.com/font-awesome/5.8.2/css/fontawesome.min.css" rel="stylesheet">
  12. 12 <script src="https://cdn.bootcss.com/font-awesome/5.8.2/js/fontawesome.min.js"></script>
  13. 13
  14. 14 <link href="https://cdn.bootcss.com/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet">
  15. 15 <script src="https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"></script>
  16. 16 </head>
  17. 17 <body>
  18. 18 <div class="container">
  19. 19 <div class="row">
  20. 20 <div class="col-md-8 col-md-offset-2">
  21. 21 <table class="table table-hover table-striped table-bordered">
  22. 22 <thead>
  23. 23 <tr>
  24. 24 <th>id</th>
  25. 25 <th>name</th>
  26. 26 </tr>
  27. 27 </thead>
  28. 28 <tbody>
  29. 29 {% for book_obj in book_list %}
  30. 30 <tr>
  31. 31 <td>{{ book_obj.pk }}</td>
  32. 32 <td>{{ book_obj.name }}</td>
  33. 33 </tr>
  34. 34 </tbody>
  35. 35 {% endfor %}
  36. 36 </table>
  37. 37 </div>
  38. 38 </div>
  39. 39 </div>
  40. 40 </body>
  41. 41 </html>

booklist.html

  1. 1 def booklist(request):
  2. 2 #动态插入100条数据
  3. 3 for i in range(100):
  4. 4 models.Book2.objects.create(name='第%s本书' %i)
  5. 5 # 查询所有的书籍展示到前端页面
  6. 6 bool_list = models.Book2.objects.all()
  7. 7 return render(request, 'booklist.html',locals())

views.py

以上是没有使用

  1. models.表名.objects.bulk_create(列表) 没有使用所以网速刷新很慢
  1. 1 def booklist(request):
  2. 2 #动态插入100000条数据 批量操作
  3. 3 l=[]
  4. 4 for i in range(10000):
  5. 5 l.append(models.Book2(name='第%s本书' %i))
  6. 6 #批量操作(插入的数据多并且速度快)
  7. 7 models.Book2.objects.bulk_create(l)
  8. 8 # 查询所有的书籍展示到前端页面
  9. 9 book_list = models.Book2.objects.all()
  10. 10 return render(request, 'booklist.html',locals())

自定义分页器

思路:

  1. 1. book_list = models.Book2.objects.all()[010]
    all()获取到Book2表中所有的书籍,列表套对象。然后列表可以切片索引(顾头不顾尾),这里是将书籍从索引为0的书籍作为第一个取出一直到索引为10的书籍展示在一个页面上;
  1. 2.每页展示10条数据
    per_page_num = 10
当前页(current_page) 起始位置(page_start) 终止位置(page_end)
1 0 10
2 10 20
3 20 30
  1. page_start = (current_page-1)*per_page_num
    page_end = current_page*per_page_num
  1. book_list = models.Book2.objects.all()[page_start:page_end
  1. 不管第1,第2,第3还是切换其他的当前页都可以显示对应的书籍序列,以上就推出了代码实现的变动。
    3.获取到访问的当前页crrent_page=request.get('page',1) 用户不传默认展示第一页
    current_page=int(current_page) 得到的是字符串,所以要转成整型,才成进行运算
  1. 在前端需要访问url的时候还需要携带手动的输入当前页(不合理)
    4.然后再引用bootstrap的分页器,再为一个页面的a标签加上携带curent_page的参数,在用户点击的时候可以跳转相应的页面,但是缺陷是我这个页面只能显示固定的当前页数
    5.如果是100条数据,一页显示10条,需要显示10页,如果是101条,需要显示11页,用代码如何实现呢?
    所以就用到了divmod

  1. 获取到数据的总条数:all_count = models.Book2.objects.all().count()
    获取到总页数:pager_nums,more=divmod(all_count,per_page_num)
    6.页码的渲染通常是单数13579符合中国人的审美标准

  1. 7.由于需要循环拿出每一个当前页,但是前端没有range方法,所以只能到后端实现了之后再传给前端
  1. pager_nums,more = divmod(all_count,per_page_num)
    if more:
    pager_nums += 1
  2.  
  3. html = ''
    for i in range(1,pager_nums+1):
    html += '<li><a href="?page=%s">%s</a></li>'%(i,i)
  1. 8.前端需要写{{page_obj.page_html|safe}} #safe将后端传入的html语法数据进行展示

自定义分页器的使用

  1. 1 from django.db import models
  2. 2
  3. 3 Create your models here.
  4. 4
  5. 5 class Book2(models.Model):
  6. 6 name = models.CharField(max_length=32)

在app01下自创的utils文件夹,导入第三方文件

  1. 1 class Pagination(object):
  2. 2 def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
  3. 3 """
  4. 4 封装分页相关数据
  5. 5 :param current_page: 当前页
  6. 6 :param all_count: 数据库中的数据总条数
  7. 7 :param per_page_num: 每页显示的数据条数
  8. 8 :param pager_count: 最多显示的页码个数
  9. 9
  10. 10 用法:
  11. 11 queryset = model.objects.all()
  12. 12 page_obj = Pagination(current_page,all_count)
  13. 13 page_data = queryset[page_obj.start:page_obj.end]
  14. 14 获取数据用page_data而不再使用原始的queryset
  15. 15 获取前端分页样式用page_obj.page_html
  16. 16 """
  17. 17 try:
  18. 18 current_page = int(current_page)
  19. 19 except Exception as e:
  20. 20 current_page = 1
  21. 21
  22. 22 if current_page < 1:
  23. 23 current_page = 1
  24. 24
  25. 25 self.current_page = current_page
  26. 26
  27. 27 self.all_count = all_count
  28. 28 self.per_page_num = per_page_num
  29. 29
  30. 30 # 总页码
  31. 31 all_pager, tmp = divmod(all_count, per_page_num)
  32. 32 if tmp:
  33. 33 all_pager += 1
  34. 34 self.all_pager = all_pager
  35. 35
  36. 36 self.pager_count = pager_count
  37. 37 self.pager_count_half = int((pager_count - 1) / 2)
  38. 38
  39. 39 @property
  40. 40 def start(self):
  41. 41 return (self.current_page - 1) * self.per_page_num
  42. 42
  43. 43 @property
  44. 44 def end(self):
  45. 45 return self.current_page * self.per_page_num
  46. 46
  47. 47 def page_html(self):
  48. 48 # 如果总页码 < 11个:
  49. 49 if self.all_pager <= self.pager_count:
  50. 50 pager_start = 1
  51. 51 pager_end = self.all_pager + 1
  52. 52 # 总页码 > 11
  53. 53 else:
  54. 54 # 当前页如果<=页面上最多显示11/2个页码
  55. 55 if self.current_page <= self.pager_count_half:
  56. 56 pager_start = 1
  57. 57 pager_end = self.pager_count + 1
  58. 58
  59. 59 # 当前页大于5
  60. 60 else:
  61. 61 # 页码翻到最后
  62. 62 if (self.current_page + self.pager_count_half) > self.all_pager:
  63. 63 pager_end = self.all_pager + 1
  64. 64 pager_start = self.all_pager - self.pager_count + 1
  65. 65 else:
  66. 66 pager_start = self.current_page - self.pager_count_half
  67. 67 pager_end = self.current_page + self.pager_count_half + 1
  68. 68
  69. 69 page_html_list = []
  70. 70 # 添加前面的nav和ul标签
  71. 71 page_html_list.append('''
  72. 72 <nav aria-label='Page navigation>'
  73. 73 <ul class='pagination'>
  74. 74 ''')
  75. 75 first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
  76. 76 page_html_list.append(first_page)
  77. 77
  78. 78 if self.current_page <= 1:
  79. 79 prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
  80. 80 else:
  81. 81 prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
  82. 82
  83. 83 page_html_list.append(prev_page)
  84. 84
  85. 85 for i in range(pager_start, pager_end):
  86. 86 if i == self.current_page:
  87. 87 temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
  88. 88 else:
  89. 89 temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
  90. 90 page_html_list.append(temp)
  91. 91
  92. 92 if self.current_page >= self.all_pager:
  93. 93 next_page = '<li class="disabled"><a href="#">下一页</a></li>'
  94. 94 else:
  95. 95 next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
  96. 96 page_html_list.append(next_page)
  97. 97
  98. 98 last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
  99. 99 page_html_list.append(last_page)
  100. 100 # 尾部添加标签
  101. 101 page_html_list.append('''
  102. 102 </nav>
  103. 103 </ul>
  104. 104 ''')
  105. 105 return ''.join(page_html_list)

my_page.py

  1. 1 from django.shortcuts import render,HttpResponse
  2. 2 from app01 import models
  3. 3 from app01.utils import my_page
  4. 4
  5. 5 def booklist(request):
  6. 6 book_list = models.Book2.objects.all()
  7. 7 all_count = book_list.count()
  8. 8 current_page = request.GET.get('page',1)
  9. 9 page_obj = my_page.Pagination(current_page=current_page,all_count=all_count)
  10. 10 page_queryset = book_list[page_obj.start:page_obj.end]
  11. 11 return render(request,'booklist.html',locals())

小总结:

  1. 自定义分页器
    页码的渲染通常都是单数13579,符号中国人的审美标准
  2.  
  3. 需要完善的
    1.加首页和尾页
    2.页码的个数应该是固定的
  4.  
  5. 自定义分页器的使用
    后端:
    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]
  6.  
  7. 前端:
    {{ page_obj.page_html|safe }} # 帮你渲染的是带有bootstrap样式的分页器

django 之 Ajax and so on的更多相关文章

  1. python Django之Ajax

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

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

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

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

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

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

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

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

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

  6. Django之Ajax提交

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

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

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

  8. Django之AJAX传输JSON数据

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

  9. Django之ajax(jquery)封装(包含 将 csrftoken 写入请求头方法)

    由于支持问题,未使用 es6 语法 _ajax.js /** * 发起请求 * @param url 请求地址 * @param data 请求数据 { } json格式 * @param type ...

  10. Django学习——图书管理系统图书修改、orm常用和非常用字段(了解)、 orm字段参数(了解)、字段关系(了解)、手动创建第三张表、Meta元信息、原生SQL、Django与ajax(入门)

    1 图书管理系统图书修改 1.1 views 修改图书获取id的两种方案 1 <input type="hidden" name="id" value=& ...

随机推荐

  1. 初识Flask框架

    Flask简介: Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架. Flask 本身相当于一个内核,其 ...

  2. plsql-工具安装部署及使用配置

    参考文档链接:https://blog.csdn.net/li66934791/article/details/83856225 简介: PL/SQL Developer是一个集成开发环境,专门开发面 ...

  3. java集合-set

    #java集合-set Map用于存储key-value的映射,其中key的值是不能重复的.并且还需要正确的覆写equals方法和hashCode方法 如果我们只需要存储不重复的key,并不需要存储对 ...

  4. localstorage二次封装-模块模式

    var db = function () { // 本地存储前缀,减少命名冲突 var prefix = 'ydb'; return { setPrefix: function (_prefix) { ...

  5. DIV的失去焦点(blur)实现

    用防抖实现DIV鼠标移出消失   由于div标签本身不支持onblur事件,所以对于点击一个按钮弹出的div,我们想要当这个div失去焦点的时候,让它消失不能使用的onblur来实现.  但是可以利用 ...

  6. html+css布局类型

    一.单列布局 1.代码如下 <!doctype html> <html> <head> <meta charset="utf-8"/> ...

  7. PC端如何下载B站里面的视频?

    此随笔只是记录一下:   PC端下载B站的视频,在blibli前面加上一个i 然后在视频上鼠标右键,视频另存为+路径即可 PS:网上其他的方法,比如在blibli前面加上kan,后面加上jj等,这些方 ...

  8. Python 获取MySql某个表所有字段名

    在使用python导出数据库中数据的时候,往往除了插入的数据以外,还有表字段等信息需要导出,查阅了资料后发现了2种方法 第一种:在mysql自带的表里查询,这个表保存了每张表的字段信息,可以用pymy ...

  9. 一起学习vue源码 - Object的变化侦测

    作者:小土豆biubiubiu 博客园:www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d 简书:h ...

  10. Linux系统是什么?亲身自学经历分享

    我是数字媒体专业学生,第一次接触LINUX的时候,是大一C语言课程里看到的,书上讲了C语言的发展历史.说到C语言的起源,就离不开UNIX系统.在20世纪60年代,贝尔实验室的研究员Ken Thomps ...