分页器与form组件
一 分页器组件介绍二 分页器的简单使用Paginator对象的属性和方法页对象的属性和方法注意!!设置表模型中默认以id排序,不然会有警告视图函数中模板中
三 分页器的进阶使用逻辑分析视图函数模板文件
四 forms组件介绍五 forms校验字段功能六 forms渲染模板功能视图函数模板
一 分页器组件介绍
项目数据量大了以后,比如涉及到分页,一页一页的加载显示django中分页器组件,把分页常用的东西,封装到一个类中实例化得到一个对象,对象里有属性和方法
二 分页器的简单使用
Paginator对象的属性和方法
from django
.core
.paginator
import Paginator
book_list
=models
.Book
.objects
.all()
paginator
=Paginator
(book_list
,10)
print(paginator
.per_page
)
print(paginator
.count
)
print(paginator
.num_pages
)
print(paginator
.page_range
)
页对象的属性和方法
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', )
视图函数中
def index(request
):
page_num_int
=int(request
.GET
.get
('page',1))
book_list
= models
.Book
.objects
.all()
paginator
= Paginator
(book_list
, 10)
page_range
= paginator
.page_range
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">«</span>
</a>
</li>
{% else %}
<-当没有上一页时,使上一页按钮无法点击->
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</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">»</span>
</a>
</li>
{% else %}
<-当没有下一页时,使下一页按钮无法点击->
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">»</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)
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
= 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">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</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">»</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">»</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
):
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}
form
=myforms
.MyForm
(data
)
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
print(form
.errors
.as_json
())
print(form
.errors
.as_data
())
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>