Django学习 day67之Django第十三日分页器与form组件

it2025-01-12  6

分页器与form组件

一 分页器组件介绍二 分页器的简单使用Paginator对象的属性和方法页对象的属性和方法注意!!设置表模型中默认以id排序,不然会有警告视图函数中模板中 三 分页器的进阶使用逻辑分析视图函数模板文件 四 forms组件介绍五 forms校验字段功能六 forms渲染模板功能视图函数模板

一 分页器组件介绍

项目数据量大了以后,比如涉及到分页,一页一页的加载显示django中分页器组件,把分页常用的东西,封装到一个类中实例化得到一个对象,对象里有属性和方法

二 分页器的简单使用

Paginator对象的属性和方法

from django.core.paginator import Paginator book_list=models.Book.objects.all() # 实例化得到对象 # 第一个参数:要分页的数据,book_list # 第二个参数:没有条数 paginator=Paginator(book_list,10) # Paginator对象的属性和方法 print(paginator.per_page) # 每页显示的条数 print(paginator.count) # 总条数,总共要分页多少条数据 print(paginator.num_pages) # 总页码数 print(paginator.page_range) # 页码的生成器 [1,2,3,4,5,6,7,8,9,10]

页对象的属性和方法

# Page类 的对象 page=paginator.page(1) # 获取第一页的对象 # 每一页的对象,属性和方法 print(page.has_next()) # 有没有下一页 print(page.next_page_number()) # 下一页页码 print(page.has_previous()) # 是否有上一页 print(page.previous_page_number()) # 上一页页面 (当前页如果是第一页,没有上一页) print(page.object_list) # 当前页的所有数据 print(page.number) # 当前页的页码数

注意!!设置表模型中默认以id排序,不然会有警告

在models.py中创建表的类中写入

class Meta: ordering=('id', ) # 默认以id排序

视图函数中

def index(request): # 需要的三个参数 page_num_int=int(request.GET.get('page',1)) # get请求接收到当前页码,默认是第一页 book_list = models.Book.objects.all() # 所有书对象 paginator = Paginator(book_list, 10) # Paginator类得对象,设置每页显示10条数据 # 需要的第一个参数:页码的生成器 [1,2,3,4,5,6,7,8,9,10] page_range = paginator.page_range # 当前生成的页码 # 需要的第二个参数,去到某一页的page对象 page = paginator.page(page_num_int) # 当前页的对象 return render(request, 'index.html', {'page_range':page_range,'page':page,'page_num_int':page_num_int})

模板中

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <title>Title</title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <table class="table"> <thead> <-表头-> <tr> <th>id</th> <th>名字</th> <th>价格</th> </tr> </thead> <tbody> {% for book in page.object_list %} <-遍历这页的所有表-> <tr> <td>{{ book.id }}</td> <td>{{ book.name }}</td> <td>{{ book.price }}</td> </tr> {% endfor %} </tbody> </table> <div class="text-center"> <nav aria-label="Page navigation"> <ul class="pagination"> {% if page.has_previous %} <-当有上一页时,使上一页按钮可点击-> <li> <a href="/?page={{ page.previous_page_number }}" aria-label="Previous"> <span aria-hidden="true">&laquo;</span> </a> </li> {% else %} <-当没有上一页时,使上一页按钮无法点击-> <li class="disabled"> <a href="" aria-label="Previous"> <span aria-hidden="true">&laquo;</span> </a> </li> {% endif %} {% for page_num in page_range %} <-遍历下方显示的所有页码-> {% if page_num_int == page_num %} <-给当前页页码按钮变色,其余的不变-> <li class="active"><a href="/?page={{ page_num }}">{{ page_num }}</a></li> {% else %} <li><a href="/?page={{ page_num }}">{{ page_num }}</a></li> {% endif %} {% endfor %} {% if page.has_next %} <-当有下一页时,使下一页按钮可点击-> <li> <a href="/?page={{ page.next_page_number }}" aria-label="Next"> <span aria-hidden="true">&raquo;</span> </a> </li> {% else %} <-当没有下一页时,使下一页按钮无法点击-> <li class="disabled"> <a href="" aria-label="Next"> <span aria-hidden="true">&raquo;</span> </a> </li> {% endif %} </ul> </nav> </div> </div> </div> </div> </body> </html>

三 分页器的进阶使用

逻辑分析

要求达到效果:最多显示前5 后5 和当前,总共11个页码,如果总页码少于11,则全部显示出来

逻辑分析 显示左5,右5,总共11个页

如果总页码大于11 1. if 当前页码减5小于1,要生成1到12的range(顾头不顾尾,共11个页码) page_range=range(1,12) 2. elif 当前页码+5大于总页码,生成总页码减10,到总页码加1的range(顾头不顾尾,共11个页码) page_range=range(paginator.num_pages-10,paginator.num_pages+1) 3. else 生成当前页码-5,到当前页码+6的列表 page_range=range(current_page_num-5,current_page_num+6)总页码小于11就直接全部显示了,生成的range就是pageinator的page_range page_range=paginator.page_range

视图函数

def index(request): # 需要的三个参数 page_num_int = int(request.GET.get('page', 1)) book_list = models.Book.objects.all() paginator = Paginator(book_list, 1) # 需要的第一个参数:页码的生成器 [1,2,3,4,5,6,7,8,9,10] # page_range = paginator.page_range if paginator.num_pages > 11: # 当前条件符合了以后,有三种情况 if page_num_int - 5 < 1: page_range = range(1, 11) elif page_num_int + 5 > paginator.num_pages: page_range = range(paginator.num_pages - 10, paginator.num_pages + 1) else: page_range = range(page_num_int - 5, page_num_int + 5) else: page_range = paginator.page_range # 需要的第二个参数,去到某一页的page对象 page = paginator.page(page_num_int) return render(request, 'index.html', {'page_range': page_range, 'page': page, 'page_num_int': page_num_int})

模板文件

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <title>Title</title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <table class="table"> <thead> <tr> <th>id</th> <th>名字</th> <th>价格</th> </tr> </thead> <tbody> {% for book in page.object_list %} <tr> <td>{{ book.id }}</td> <td>{{ book.name }}</td> <td>{{ book.price }}</td> </tr> {% endfor %} </tbody> </table> <div class="text-center"> <nav aria-label="Page navigation"> <ul class="pagination"> {% if page.has_previous %} <li> <a href="/?page={{ page.previous_page_number }}" aria-label="Previous"> <span aria-hidden="true">&laquo;</span> </a> </li> {% else %} <li class="disabled"> <a href="" aria-label="Previous"> <span aria-hidden="true">&laquo;</span> </a> </li> {% endif %} {% for page_num in page_range %} {% if page_num_int == page_num %} <li class="active"><a href="/?page={{ page_num }}">{{ page_num }}</a></li> {% else %} <li><a href="/?page={{ page_num }}">{{ page_num }}</a></li> {% endif %} {% endfor %} {% if page.has_next %} <li> <a href="/?page={{ page.next_page_number }}" aria-label="Next"> <span aria-hidden="true">&raquo;</span> </a> </li> {% else %} <li class="disabled"> <a href="" aria-label="Next"> <span aria-hidden="true">&raquo;</span> </a> </li> {% endif %} </ul> </nav> </div> </div> </div> </div> </body> </html>

四 forms组件介绍

注册功能,登录功能,前端需要校验(字段长度,邮箱是否合法。。。)前端校验可以没有,后端校验是必须的,使用传统方式 if判断写的很多借助于forms组件,可以快速实现字段的校验 from django.forms import Form

五 forms校验字段功能

新建myforms.py,写一个类,类里写要校验的字段 class MyForm(forms.Form): # 校验这个字段,最大长度是32,最小长度是3 name = forms.CharField(required=False, max_length=32, min_length=3,label='用户名') email = forms.EmailField(label='邮箱') age=forms.IntegerField(max_value=200,min_value=0,label='年龄') 视图函数中使用 from app01 import myform def register(request): # 数据可以是从前端传过来的,也可以是自己后台的数据 # 我现在有以下数据 data={'name':'lqz','email':'33333@qq.com','age':900} # data={'email':'33333@qq.com','age':100} # data={'age':100} # 校验数据是否合法 # 实例化得到form对象,把要校验的数据传入 form=myforms.MyForm(data) # 校验数据:form.is_valid() 返回布尔类型 if form.is_valid(): print('校验通过') # 校验通过的数据 print(form.cleaned_data) # 不一定是上面传入的数据 else: print(form.cleaned_data) print('校验失败') # 哪个字段失败了?失败的原因是什么 print(form.errors) print(type(form.errors)) from django.forms.utils import ErrorDict #### 重写了__str__ print(form.errors.as_json()) print(form.errors.as_data()) # form.errors.as_ul() # 是为了渲染模板 return HttpResponse('ok')

六 forms渲染模板功能

视图函数

def register(request): if request.method=='GET': form=myforms.MyForm() return render(request,'register.html',{'form':form}) elif request.method=='POST': # 数据校验 form=myforms.MyForm(request.POST) if form.is_valid(): print('校验通过,存数据库') else: print(form.errors.as_data()) print('校验失败,返回错误') return HttpResponse('ok')

模板

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <hr> <h1>手动创建模板</h1> <form action="" method="post"> <p>用户名:<input type="text" name="name"></p> <p>邮箱:<input type="text" name="email"></p> <p>年龄:<input type="text" name="age"></p> <p><input type="submit" value="提交"></p> </form> <hr> <h1>半自动渲染模板1</h1> <form action="" method="post"> <p>用户名:{{ form.name }}</p> <p>邮箱:{{ form.email }}</p> <p>年龄:{{ form.age }}</p> <p><input type="submit" value="提交"></p> </form> <h1>半自动渲染模板2(用的最多)</h1> <form action="" method="post"> <p>{{ form.name.label }}--{{ form.name }}</p> <p>{{ form.email.label }}---{{ form.email }}</p> <p>{{ form.age.label }}---{{ form.age }}</p> <p><input type="submit" value="提交"></p> </form> <h1>半自动渲染模板3(用的最多)</h1> <form action="" method="post"> {% for foo in form %} <p>{{ foo.label }} :{{ foo }}</p> {% endfor %} <p><input type="submit" value="提交"></p> </form> <h1>全自动(了解)</h1> <form action="" method="post"> {# {{ form.as_ul }}#} {{ form.as_p }} {# <table>#} {# {{ form.as_table }}#} {# </table>#} <p><input type="submit" value="提交"></p> </form> </body> </html>
最新回复(0)