分页器与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>