django进阶

django的分页器

基础语法:

//Paginator对象:

//类Paginator:
class Paginator(object_list,per_page,orphans=0,allow_empty_first_page=True)

//必须提供的参数:

object_list:一个列表或元组,元素是django QuerySet或是包含count()或__len__()方法的可切片对象。
per_page:包含在一页中最多的条目数量。

//可选参数:

//orphans:在最后一页中充许的最少条目数量,默认是0.当最后一页条目数量小于或等于orphans时,这些条目加到本页的上一页中。
//allow_empty_first_page:是否充许第一页为空。如设为False且object_list为空,则抛出EmptyPage异常。

//方法:

Paginator.page(number):返回一个Page对象,序号是始于1.如给出的页号不存在,抛出InvalidPage异常。

//属性:

//Paginator.num_pages:页面总页数
//Paginator.page_range:页面数的范围,始于1,如[1,2,3,4]。

//InvalidPage异常:

//如要求的页面无效或页面中没有对象,page()抛出InvalidPage异常。
//PageNotAnInterger:当提供给page()的数不是整数是抛出该异常。
//EmptyPage:当提供给page()的数是一个有效数,但在该页没有对象存在时,抛出该异常。

//Page对象:

class Page(object_list,number,paginator):
//一般不手工创建Pages,可以使用Paginator.page().

//方法:

Page.has_next():如有下一页则返回True
Page.has_previous():如有上一页则返回True
Page.has_other_pages():如有上一页或下一页返回True
Page.next_page_number():返回下一页的页码。不管下一页是否存在都返回。
Page.previous_page_number():返回上一页的页码。不管上一页是否存在都返回。
Page.start_index():返回当前页面中第一个对象的序号,序号始于1.例如:将一个包含5个对象的列表分成每页2个对象,则第二页的start_index()返回3.
Page.end_index():返回当前页面中最一个对象的序号。

//属性:

//Page.object_list:当前页面中所有的对象
//Page.number:当前页面的页码,始于1
//Page.paginator:页面相关的Pageinator对象。        
          
View Code

简单练习:

分页是Web应用常用的手法,Django提供了一个分页器类Paginator(django.core.paginator.Paginator),可以很容易的实现分页的功能。该类有两个构造参数,一个是数据的集合,另一个是每页放多少条数据。Paginator的基本使用如下:

$python manage.py shell

>>> from django.core.paginator import Paginator

>>> objects = ['john', 'paul', 'george', 'ringo']

>>> p = Paginator(objects, 2)      #每页两条数据的一个分页器

>>> p.count        #数据总数

4

>>> p.num_pages      #总页数

2

>>>p.page_range       #页码的列表

[1, 2]

>>> page1 = p.page(1)     #第1页

>>> page1

<Page 1 of 2>

>>> page1.object_list     #第1页的数据

['john', 'paul']

>>> page2 = p.page(2)

>>> page2.object_list      #第2页的数据

['george', 'ringo']

>>> page2.has_next()     #是否有后一页

False

>>> page2.has_previous()   #是否有前一页

True

>>> page2.has_other_pages()   #是否有其他页

True

>>> page2.next_page_number()  #后一页的页码

3

>>> page2.previous_page_number()  #前一页的页码

1

>>> page2.start_index()   # 本页第一条记录的序数(从1开始)

3

>>> page2.end_index()    # 本页最后录一条记录的序数(从1开始)

4

>>> p.page(0)               #错误的页,抛出异常

...EmptyPage: That page number is less than 1

>>> p.page(3)              #错误的页,抛出异常

...EmptyPage: That page contains no results


其实前面scaffold生成的内容里面就已经包含了分页的功能,相信有了对Paginator的了解,你自己就可以看懂在view函数和模板中如何使用分页器了。
View Code

实例应用:

from django.shortcuts import render,HttpResponse

# Create your views here.
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger


def index(req):

    user_list=["用户"+str(i) for i in range(100)]

    user_list=getPage(req,user_list)

    return render(req,"index.html",locals())


def getPage(req,user_list):

    paginator=Paginator(user_list,5)

    try:
        current_page=req.GET.get("page",1) #  http://127.0.0.1:8000/index/?page=20
        article_list=paginator.page(current_page)
    except (EmptyPage,InvalidPage,PageNotAnInteger):
        article_list=paginator.page(1)

    return user_list


#*******----------index.html
{% for i in user_list %}
    <p>{{ i }}</p>
{% endfor %}
View Code

自定义分页:

from django.shortcuts import render,HttpResponse

# Create your views here.
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger


def index(req):

    user_list_all=["用户"+str(i) for i in range(1000)]
    #需要分页显示

    current_page=int(req.GET.get("page",1))

    # start=(current_page-1)*5
    # end=(current_page-1)*5+5
    start=(current_page-1)*10
    end=(current_page-1)*10+10

    user_list=user_list_all[start:end]
    #不能让用户去url写page,所以写入Page Number
    #问题是:显示多少页码(Page Number)?

    total_item=len(user_list_all)
    pageNumber,remaining=divmod(total_item,10)  #每页显示10条数据
    if remaining>0:
        pageNumber+=1

    list_tag=[]

    #默认最多显示10页码
    PN=6
    half_PN=int(PN/2)
    if pageNumber<PN:
        BEGIN=0
        END=pageNumber
    else:
        if current_page>half_PN:

            if current_page<(pageNumber-half_PN):
                BEGIN=current_page-half_PN
                END=current_page+half_PN
            else:
                #最后几页不需要再增加新的页码
                BEGIN=pageNumber-PN
                END=pageNumber
        else:
            BEGIN=0
            END=PN

    baseurl='/index/?page='

    if current_page<=1:
        first="<a href='#'>首页</a>"
    else:
        first="<a href='%s%d'>首页</a>" % (baseurl,1)
    list_tag.append(first)

    if current_page<=1:
        prev="<a href=''>上一页</a>"
    else:
        prev="<a href='%s%d'>上一页</a>" % (baseurl,current_page-1)
    list_tag.append(prev)

    for i in range(BEGIN+1,END+1):
        if i == current_page:
            temp="<a href='%s%d' class='active'>%d</a>" % (baseurl,i,i)
        else:
            temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
        list_tag.append(temp)
    if current_page>=pageNumber:
        next="<a href='#'>下一页</a>"
    else:
        next="<a href='%s%d'>下一页</a>" % (baseurl,current_page+1)
    list_tag.append(next)
    if current_page>=pageNumber:
        last="<a href='#'>末页</a>"
    else:
        last="<a href='%s%d'>末页</a>" % (baseurl,pageNumber)

    list_tag.append(last)

    tags="".join(list_tag)

    return render(req,"index.html",locals())



#------------------------------------index.html
#------------------------------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pager a{
            display: inline-block;
            width: 60px;
            height: 20px;
            padding: 5px;
            background-color: darkgrey;
            color: #2459a2;
            text-decoration: none;
            text-align: center;
            line-height: 20px;
        }
        .pager a.active{
            color: white;
            background-color: red;
        }
    </style>
</head>
<body>


{% for user in user_list %}
    <p>{{ user }}</p>
{% endfor %}
<div class="pager">
    {{ tags|safe }}
</div>

</body>
</html>
View Code

form表单系统

原生form

#*****************************models.py#*****************************

from django.db import models

# Create your models here.


class Info(models.Model):

    username = models.CharField(max_length=64)
    telephone = models.CharField(max_length=64)
    email=models.CharField(max_length=64,default='')
    password=models.CharField(max_length=64,default='')
    
#*****************************url.py#*****************************

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^register/', views.register,name='register'),

]
#*****************************views.py#*****************************

from django.shortcuts import render,HttpResponse

# Create your views here.


from app01.models import *

def register(req):


    if req.method=='POST':
        # 问题1:每一字段都要单独取,单独设置

        user=req.POST.get('user')
        phone=req.POST.get('phone')
        email=req.POST.get('email')
        pwd=req.POST.get('pwd')

        obj=Info.objects.filter(username=user,
                                telephone=phone,
                                password=pwd,

                                email=email,)
        # 问题2 所有的输入是否正确,完全需要自己从头写
        error_obj=""
        if len(user)==0:
            error_obj="用户名不能为空!"

        if not (obj or error_obj) :

            Info.objects.create(username=user,
                                telephone=phone,
                                password=pwd,
                                email=email,
                                )

            return HttpResponse('添加成功!')

        else:
            # 问题3: 页面不断刷新,导致已写对的字段信息也没了,需要重写(ajax不需要)
            return render(req,'register.html',locals())

    return render(req,'register.html')

#*****************************register.html#*****************************
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加个人信息</title>

</head>
<body>
     <h1>注册个人信息</h1>

     <form action="{% url 'register' %}" method="post">

           姓名 <input type="text" name="user"> <span class="user">{{ error_obj }}</span><br>
           手机 <input type="text" name="phone"><span class="phone"></span><br>
           邮箱 <input type="text" name="email"><span class="email"></span><br>
           密码 <input type="text" name="pwd">  <span class="pwd"></span><br>

           <input type="submit" value="提交"><br>

          {% csrf_token %}
     </form>
</body>
</html>
View Code

Django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm

关于django的表单系统,主要分两种

基于django.forms.Form:所有表单类的父类

基于django.forms.ModelForm:可以和模型类绑定的Form

django的form

from django.shortcuts import render,HttpResponse

# Create your views here.


from app01.models import *

from django import forms
from app01 import models
from django.core.exceptions import ValidationError


class regiserForm(forms.Form):

    def validate_user(value):
        try:
            models.Info.objects.get(username=value)
            raise ValidationError('%s 的信息已经存在!'%value)
        except models.Info.DoesNotExist:
            pass

    #注意,字段名字一定是前端input标签的属性name的值
    user=forms.CharField(validators=[validate_user],min_length=5,error_messages={'required':'必填'})
    pwd=forms.CharField(min_length=5,widget=forms.PasswordInput())
    phone=forms.CharField(min_length=5)
    email=forms.EmailField(min_length=5,widget=forms.TextInput(
        attrs={'class':'emailFormset',
        'value':'123@qq.com'}
    ))

    sex_choice=((0,''),
                (1,''))#select的数据可以像这样写,也可以在另外一张表中动态去拿

    sex=forms.IntegerField(widget=forms.widgets.Select(choices=sex_choice,

                                                       attrs={'class':'selectForm2'}
                                                       ))
    #思考:label怎么用?

def register(req):

    form_obj=regiserForm()

    if req.method=='POST':

        form_obj=regiserForm(req.POST)
        if form_obj.is_valid():
            models.Info.objects.create(
                username=form_obj.cleaned_data["user"],
                password=form_obj.cleaned_data["pwd"],
                telephone=form_obj.cleaned_data["phone"],
                email=form_obj.cleaned_data["email"],
                sex=form_obj.cleaned_data["sex"],
            )

            return HttpResponse("添加成功!")


        else:
            error_obj=form_obj.errors

            '''
            print(form_obj.errors,type(form_obj.errors))
            from django.forms.utils import ErrorDict
            print(form_obj.errors["user"][0])
            print(form_obj.errors["email"][0])#Enter a valid email address.
            print(form_obj.errors["email"][1])#Ensure this value has at least 5 characters (it has 3).
            '''

            #return render(req,'register.html',locals())

    return render(req,'register.html',locals())
#-----------------------------models.py-----------------------------#
class Info(models.Model):

    username = models.CharField(max_length=64)
    telephone = models.CharField(max_length=64)
    email=models.CharField(max_length=64,default='')
    password=models.CharField(max_length=64,default='')

    sex=models.CharField(max_length=32,default='')#存的是字符串1或者0,不能IntegerField
    
#-----------------------------register.py-----------------------------#
     <h1>注册个人信息</h1>

     <form action="{% url 'register' %}" method="post">

           <!--
           姓名 <input type="text" name="user"> <span class="user"></span><br>
           手机 <input type="text" name="phone"><span class="phone"></span><br>
           邮箱 <input type="text" name="email"><span class="email"></span><br>
           密码 <input type="password" name="pwd">  <span class="pwd"></span><br>
           !-->

           姓名 {{ form_obj.user }}  <span class="user">{{ error_obj.user.0 }}</span><br>
           手机 {{ form_obj.phone }} <span class="phone">{{ error_obj.phone.0 }}</span><br>
           邮箱 {{ form_obj.email }} <span class="email">{{ error_obj.email.0 }}</span><br>
           密码 {{ form_obj.pwd }}   <span class="pwd">{{ error_obj.pwd.0 }}</span><br>


           密码 {{ form_obj.sex }}   <span class="sex">{{ error_obj.sex.0 }}</span><br>

           <input type="submit" value="提交"><br>

          {% csrf_token %}
     </form>
View Code

django的ModelForm

 

http://python.usyiyi.cn/django/topics/forms/index.html 

 

 

 

 

 

 

 

 

 

一 什么是Form?什么是DjangoForm?

Django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm

关于django的表单系统,主要分两种

基于django.forms.Form:所有表单类的父类

基于django.forms.ModelForm:可以和模型类绑定的Form

 

posted @ 2016-12-28 15:35  Yuan先生  阅读(1362)  评论(0编辑  收藏  举报