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对象。
简单练习:
分页是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函数和模板中如何使用分页器了。
实例应用:
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 %}
自定义分页:
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>
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>
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>
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