Web框架之Django进阶篇
一、Django内置分页
在Django中需要使用内置的分页时,需要导入下面的模块。
from django.shortcuts import render from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger user_list = [] for i in range(1,999): temp = {'name':'root'+str(i),'age':i} user_list.append(temp) #Django内置分页 def index1(request): current_page=request.GET.get('p') paginator = Paginator(user_list,10) #per_page:每页显示条目数量 #count: 数据总个数 #num_page:总页数 #page_range:总页数的索引范围,如(1,10),(1,200) #page:page对象 try: posts=paginator.page(current_page) #has_next 是否有下一页 #next_page_number 下一页页码 #has_previous 是否有上一页 #previous_page_number 上一页页码 #object_list 分页之后的数据列表 #number 当前页 #paginator paginator对象 except PageNotAnInteger: posts=paginator.page(1) except EmptyPage: posts=paginator.page(paginator.num_pages) return render(request,'index1.html',{'posts':posts})
<ul> {#{% for row in posts %}#} {# 一样效果 #} {% for row in posts.object_list %} <li>{{ row.name }}-{{ row.age }}</li> {% endfor %} {% include 'include/pager.html' %} {# 引用include目录下的页面跳转 #} </ul> pager.html: {% if posts.has_previous %} <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a> {% else %} <a href="javascript:;">上一页</a> {% endif %} {% if posts.has_next %} <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a> {% endif %} <span> {{ posts.number }}/{{ posts.paginator.num_pages }} </span>
在Django自带的内置分页中,由于没有显示页码的功能,所以当我们需要使用当页码功能时,就需要修改源码了,但是并不推荐这样做,因为如果其他项目中需要页码功能时又要我们修改源码,所以这里我们可以自定制一个页码功能,当我们需要时调用就ok了。
from django.shortcuts import render from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger user_list = [] for i in range(1,666): temp = {'name':'root'+str(i),'age':i} user_list.append(temp) # Create your views here. # ****************************************Django分页********************************************** #自定制类分页(显示页码) class CustomPaginator(Paginator): def __init__(self,current_page,per_pager_num,*args,**kwargs): # 当前页 self.current_page=int(current_page) # 显示最多的页码数量 11 self.per_pager_num=int(per_pager_num) super(CustomPaginator,self).__init__(*args,**kwargs) #运用继承Paginator的功能 def pager_num_range(self): #当前页 #self.current_page #最多页码数量 # self.per_pager_num #总页数 # self.num_pages if self.num_pages < self.per_pager_num: #条件1:当总页数小于要显示的页码时 * return range(1,self.num_pages+1) # 条件2:当总页数大于要显示的页码时 ** part = int(self.per_pager_num/2) #中间页码 ** if self.current_page <= part: #当前所在的页码小于中间页码,显示1-11页 ** return range(1,self.per_pager_num+1) if (self.current_page + part) > self.num_pages: #条件3:当页码到总页数时,不能再增加页码 *** return range(self.num_pages-self.per_pager_num+1,self.num_pages+1) return range(self.current_page-part,self.current_page+part+1) #当前所在页码大于中间页码,需要改变页码 ** #Django内置分页 def index1(request): current_page=request.GET.get('p') paginator = CustomPaginator(current_page,11,user_list,10) #每页10个数据 #per_page:每页显示条目数量 #count: 数据总个数 #num_page:总页数 #page_range:总页数的索引范围,如(1,10),(1,200) #page:page对象 try: posts=paginator.page(current_page) #has_next 是否有下一页 #next_page_number 下一页页码 #has_previous 是否有上一页 #previous_page_number 上一页页码 #object_list 分页之后的数据列表 #number 当前页 #paginator paginator对象 except PageNotAnInteger: posts=paginator.page(1) except EmptyPage: posts=paginator.page(paginator.num_pages) return render(request,'index1.html',{'posts':posts})
{#***********************************Django内置分页*********************************#}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
{#{% for row in posts %}#} {# 一样效果 #}
{% for row in posts.object_list %}
<li>{{ row.name }}-{{ row.age }}</li>
{% endfor %}
{% include 'include/pager.html' %} {# 引用include目录下的页面跳转 #}
</ul>
</body>
</html>
pager.html:
{% if posts.has_previous %}
<a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a>
{% else %}
<a href="javascript:;">上一页</a>
{% endif %}
{#显示页码,这里调用的是自定制类中的pager_num_range方法#}
{% for i in posts.paginator.pager_num_range %}
{% if i == posts.number %}
<a style="font-size: 20px" href="/index1.html?p={{ i }}">{{ i }}</a>
{% else %}
<a href="/index1.html?p={{ i }}">{{ i }}</a>
{% endif %}
{% endfor %}
{% if posts.has_next %}
<a href="/index1.html?p={{ posts.next_page_number }}">下一页</a>
{% endif %}
{#当前在多少页#}
<span>
{{ posts.number }}/{{ posts.paginator.num_pages }}
</span>
二、Form组件
一、简单概括一下Form组件的两个功能:
①对用户请求的验证(需要导入模块)
②生成HTML
- 对用户请求的验证 - Ajax - Form - 生产HTML代码 a.创建一个类 b.类中创建字段(包含正则表达式) c.GET obj = Fr() obj.user => 自动生成HTML d.POST obj = Fr(request.POST) if obj.is_valid(): print(obj.cleaned_data) //字典形式的数据 else: print(obj.errors) //错误信息 return render(request,'f1.html',{'obj':obj})
from django.shortcuts import render,redirect from django.shortcuts import HttpResponse from django import forms from django.forms import fields # Create your views here. class f1Form(forms.Form): user = forms.CharField(required=True,min_length=2,max_length=8,error_messages={ 'required':'用户名不能为空', 'max_length':'长度太长了', 'min_length':'长度太短了' }) pwd = forms.CharField(required=True,min_length=6,max_length=20,error_messages={ 'required': '密码不能为空', 'max_length': '长度太长了', 'min_length': '长度太短了' }) age = forms.IntegerField(required=True,error_messages={'required':'年龄不能为空','invalid':'格式错误哦'}) email = forms.EmailField(required=True,error_messages={'required':'邮件不能为空','invalid':'格式错误哦'}) def f1(request): if request.method == "GET": obj = f1Form() return render(request,'f1.html',{'obj':obj}) else: obj = f1Form(request.POST) #用户提交数据 if obj.is_valid(): print('验证成功',obj.cleaned_data) #提交的数据,字典形式 return redirect('http://baidu.com') else: print('验证失败',obj.errors) return render(request,'f1.html',{'obj':obj})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Form验证</title> </head> <body> <form action="/f1.html" method="post"> <p>{{ obj.user }}{{ obj.errors.user.0 }}</p> {# 第一个是Form组件自动生成的HTML,第二个是错误信息 #} <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p> <p>{{ obj.age }}{{ obj.errors.age.0 }}</p> <p>{{ obj.email }}{{ obj.errors.email.0 }}</p> <p><input type="submit" value="提交"></p> </form> </body> </html>
二、Form组件的一些字段、生成HTML插件、以及验证功能的扩展:
https://www.cnblogs.com/ray-h/p/10184079.html
三、序列化
Django中的序列化主要应用在用户对数据库请求数据时发送给前端的数据,特别的Ajax请求一般返回的为Json格式。
数据库返回的数据有3种类型:
① 对象 <QuerySet([ obj , obj , obj ])>
② 字典 <QuerySet([ { 'id':1,'user':'Ray' } , { 'id':2,'user':'Alex' } , { 'id':1,'user':'Jack' } ])>
③ 元祖 <QuerySet([ (1,'Ray') , (2,'Alex') , (3,'Jack') ])>
例子:
Ajax请求数据时获得 -> success:function(arg){},此时需要根据arg的状态判断是否请求成功,假如后台使用字典的形式传送给前端
==> response = {'stutas':True , 'msg':None}
- 需要把cleaned_data中的数据序列化成字符串
A.对象(QuerySet[obj,obj,obj])
- 使用模块
ret = {'stutas':True,'data':None}
from django.core import serialziers
user_list = UserInfo.objects.all()
ret['data'] = serializers.serializer("json",user_list)
B.字典(QuerySet[{'id':1,'user':'ray1'},{'id':2,'user':'ray2'},{'id':3,'user':'ray3'}])
- 使用list
user_list = UserInfo.objects.all()
ret['data'] = list(user_list)
C.元祖(QuerySet[(1,'ray1'),(2,'ray2')])
- 使用list
user_list = UserInfo.objects.all()
ret['data'] = list(user_list)
- 总结:
- ①上面的序列化只能把返回给前端ret字典中的数据 ==> ret['data']序列化成字符串;
- ②然后数据返回给前端Ajax获取时还是需要把ret字典转换为前端识别的json字符串
==> return HttpResponese(json.dumos(ret))
浙公网安备 33010602011771号