day72 分页组件和form组件

it2023-10-05  74

目录

昨日回顾今日内容1 分页器组件介绍2 分页器的简单使用视图Paginator对象和Page对象的属性和方法实现批量插入数据的两种方式分页的基本使用 模板models 3 分页器的进阶使用视图模板 4 forms组件介绍5 forms校验字段功能6 forms渲染模板功能

昨日回顾

1 ajax:异步的javascript的xml,同时可以发出很多ajax的请求,局部刷新 2 本质就是使用javascript这门语言发送http请求,(异步),原生,jquery的ajax方法,axios 3 如何使用(借助于jquery) # 默认编码方式是urlencoded $.ajax({ url:/books/?name=lqz, method:'post/get', data:{name:'lqz',age:19}, success:function (data){ 打印,弹窗,渲染页面(js dom操作,修改页面) } }) 4 上传文件 var formdata=new Formdata() formdata.append('name','lqz') formdata.append('myfile',$('#id_file')[0].files[0]) $.ajax({ url:/books/?name=lqz, method:'post/get', processData:false, contentType:false, data:formdata, success:function (data){ 打印,弹窗,渲染页面(js dom操作,修改页面) } }) # 后端代码写一套即可:使用form表单传,postman,ajax传,都是一样的 5 上传json格式 $.ajax({ url:/books/?name=lqz, method:'post/get', contentType:'application/json', data:字符串(json格式), success:function (data){ 打印,弹窗,渲染页面(js dom操作,修改页面) } }) 6 后端返回数据 -HttpResponse:它没有指定,text/html -JsonResponse:它指定了响应编码:application/json -ajax方法:会去看响应编码是什么,如果是application/json,自动调用JSON.parser(),如果不是json格式,就不处理 -于是:success:function (data) 可能是个字符串,也可能是个对象,响应编码决定的 7 js中json序列化和反序列化 -JSON.parser() -JSON.stringify(data) 8 django内置的序列化器 -需要会自己转(把对象转成json格式) -自己写(局限性,以后再转publish,还得再写一遍,不通用) ll=[] for book in book_list: ll.append({'name':book.name,'age':book.age}) return JsonResponse(ll,safe=False) {name:lqz,age:18,hobbys:[{hobbyname:'篮球',hobbyid:1},{hobbyname:'足球',hobbyid:2}]} [{name:lqz,age:18},{name:egon,age:18},{name:zs,age:18}]

今日内容

1 分页器组件介绍

1 项目数据量大了以后,比如涉及到分页,一页一页的加载显示 2 django中分页器组件,把分页常用的东西,封装到一个类中 3 实例化得到一个对象,对象里有属性和方法

2 分页器的简单使用

视图

Paginator对象和Page对象的属性和方法

先导入分页器的类

from django.core.paginator import Paginator

然后在视图函数中写Paginator对象和Page对象的属性和方法

Paginator对象的属性和方法

def index(reuest): book_list=models.Book.objects.all() # 实例化得到对象 # 第一个参数:要分页的数据,book_list # 第二个参数:没有条数 paginator=Paginator(book_list,10) # Paginator对象的属性和方法 print(paginator.per_page) # 每页显示的条数 print(paginator.count) # 总条数,总共要分页多少条数据 print(paginator.num_pages) # 总页码数 print(paginator.page_range) # 页码的生成器 [1,2,3,4,5,6,7,8,9,10]

Page对象的属性和方法

Page类 的对象 page=paginator.page(2) # 第一页的对象 # 每一页的对象,属性和方法 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排序 class Meta: ordering=('id', ) # 默认以id排序

实现批量插入数据的两种方式

from django.shortcuts import render,HttpResponse from app01 import models def index(request): #方式一: for i in range(100): models.Book.objects.create(name='书籍%s'%i,price=i+1) #方式二: l=[] for i in range(100): book=models.Book(name='书籍%s'%i,price=i+1) l.append(book) models.Book.objects.bulk_create(l,10) return render(request, 'index3.html')

分页的基本使用

def index(request): # 需要的第三个参数 page_num_int=int(request.GET.get('page',1)) book_list = models.Book.objects.all() paginator = Paginator(book_list, 10) # 需要的第一个参数:页码的生成器 [1,2,3,4,5,6,7,8,9,10] page_range = paginator.page_range # 需要的第二个参数,去到某一页的page对象 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">&laquo;</span> </a> </li> {% else %} <li class="disabled"> <a href="" aria-label="Previous"> <span aria-hidden="true">&laquo;</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">&raquo;</span> </a> </li> {% else %} <li class="disabled"> <a href="" aria-label="Next"> <span aria-hidden="true">&raquo;</span> </a> </li> {% endif %} </ul> </nav> </div> </div> </div> </div> </body> </html>

models

from django.db import models class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) class Meta: ordering=('id', ) # 默认以id排序

3 分页器的进阶使用

# 最多显示前5 后5 和当前,总共11个页码,如果少于11,全部显示出来 #逻辑分析 显示左5,右5,总共11个页, 1 如果总页码大于11 1.1 if 当前页码减5小于1,要生成112的列表(顾头不顾尾,共11个页码) page_range=range(1,12) 1.2 elif 当前页码+5大于总页码,生成当前页码减10,到当前页码加1的列表(顾头不顾尾,共11个页码) page_range=range(paginator.num_pages-10,paginator.num_pages+1) 1.3 else 生成当前页码-5,到当前页码+6的列表 page_range=range(current_page_num-5,current_page_num+6) 2 其它情况,生成的列表就是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) # 需要的第一个参数:页码的生成器 [1,2,3,4,5,6,7,8,9,10] # page_range = paginator.page_range 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对象 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">&laquo;</span> </a> </li> {% else %} <li class="disabled"> <a href="" aria-label="Previous"> <span aria-hidden="true">&laquo;</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">&raquo;</span> </a> </li> {% else %} <li class="disabled"> <a href="" aria-label="Next"> <span aria-hidden="true">&raquo;</span> </a> </li> {% endif %} </ul> </nav> </div> </div> </div> </div> </body> </html>

4 forms组件介绍

1 注册功能,登录功能,前端需要校验(字段长度,邮箱是否合法。。。) 2 前端校验可以没有,后端校验是必须的,使用传统方式 if判断写的很多 3 借助于forms组件,可以快速实现字段的校验 from django.forms import Form

5 forms校验字段功能

### 1 在myform.py文件里写一个类,类里写要校验的字段 class MyForm(forms.Form): # 校验这个字段,最大长度是32,最小长度是3 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='年龄') ### 2 视图函数中使用 def register(request): # 数据可以是从前端传过来的,也可以是自己后台的数据 # 我现在有以下数据 data={'name':'lqz','email':'33333@qq.com','age':900} # data={'email':'33333@qq.com','age':100} # data={'age':100} # 校验数据是否合法 # 实例化得到form对象,把要校验的数据传入 form=myforms.MyForm(data) # 校验数据:form.is_valid() 返回布尔类型 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 #### 重写了__str__ print(form.errors.as_json()) print(form.errors.as_data()) # form.errors.as_ul() # 是为了渲染模板 return HttpResponse('ok')

6 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>
最新回复(0)