Day 11分页器和from组件

it2023-10-30  66

Day 11分页器和from组件

一、批量写入数据

方式一

from faker import Faker from app01 import models import random f = Faker(locale='zh/CN') def index(request): for i in range(100): models.User.objects.create( name=f.name, age=random.randint(0, 1), salary=random.randint(8000.15000), address=f.addres() )

这样的方法不推荐,相当于启动了100次数据库,对数据库压力比较大

方式二

使用django.db.models.query.QuerySet.==bulk_create()==批量创建对象,减少SQL查询次数。改进如下:

def bulk_create(self, objs, batch_size=None): objs = list(objs)

objs 为列表格式 batch_size分几次写入,默认一次

def index(request): user_list = [] for i in range(100): user = models.User( name=f.name, age=random.randint(0, 1), salary=random.randint(8000.15000), address=f.addres() ) user_list.append(user) models.User.objects.bulk_create(user_list, 10) # 分十次写入

牺牲内存减少数据库压力

二、分页器的使用

1 分页器组件介绍

1 项目数据量大了以后,比如涉及到分页,一页一页的加载显示 2 django中分页器组件,把分页常用的东西,封装到一个类中 3 实例化得到一个对象,对象里有属性和方法 # 实例化得到对象 # 第一个参数:要分页的数据,book_list # 第二个参数:显示的条数 paginator = Paginator(user_list, 9)

2 Paginator常用属性和方法:

(1)count:总共有多少条数据。

(2)num_pages:总共有多少页

(3)per_page:每页显示的条数

(4)page_range:页面的区间。比如有三页,那么就是range(1,4)。

3 Page常用属性和方法:

(1)has_next:是否还有下一页。

(2)has_previous:是否还有上一页。

(3)next_page_number: 下一页的页码。

(4)previous_page_number:上一页的页码:

(5)number:当前页。

(6)start_index: 当前这一页的第一条数据的索引值。

(7)end_index:当前这一页的最后一条数据的索引值。

分页器使用(带省略号)

视图

def index(request): current_page = int(request.GET.get('page', 1)) # get请求 如果没有默认取1 # print(request.GET) # print(current_page) user_list = models.User.objects.all() # 实例化得到对象 # 第一个参数:要分页的数据,book_list # 第二个参数:显示的条数 paginator = Paginator(user_list, 5) # 页码生成器 page_range = [] # 需要显示的页码数 # 去到某一页的page对象 single_user_list = paginator.page(current_page) # 当前页码数 page_all = paginator.num_pages # 总页码数· mid_pages = 3 # 中间段显示的页码数 page_goto = 1 # 默认跳转的页码 if page_all <= 2 + mid_pages: # 当页码数量小于6个时候 page_range = paginator.page_range # 全部显示 else: # 添加应该显示的页码 page_range += [1, page_all] # 列表的扩充 page_range += [current_page - 1, current_page, current_page + 1] # 当前页是头尾 范围拓展2页 if current_page == 1 or current_page == page_all: page_range += [current_page - 2, current_page + 2] # 去掉超出范围的页码 page_range = filter(lambda x: x > 0 and x < page_all + 1, page_range) # print(page_range) # 排序去重 page_range = sorted(list(set(page_range))) print(page_range) # 查漏补缺 # 从第二个开始遍历,查看页码间隔,若间隔为0则是连续的 # 若间隔为1则不上页码:间隔超过1 补上省略号 t = 1 for i in range(len(page_range) - 1): step = page_range[t] - page_range[t - 1] if step >= 2: if step == 2: page_range.insert(t, page_range[t] - 1) else: page_goto = page_range[t - 1] + 1 page_range.insert(t, '...') t += 1 t += 1 # 优化结果后的页码列表 paginator.page_range_new = page_range # 默认跳转页的值 paginator.page_goto = page_goto paginator.current_page = current_page return render(request, 'index.html', { 'paginator': paginator, 'user_list': user_list, 'single_user_list': single_user_list, })

html

<div class="col-md-6 col-md-offset-3"> <table class="table table-striped"> <thead> <tr> <th>序号</th> <th>名字</th> <th>年龄</th> <th>薪资</th> <th>地址</th> </tr> </thead> <tbody> {% for user in single_user_list %} <tr> <th>{{ user.id }}</th> <th>{{ user.name }}</th> <th>{{ user.age }}</th> <th>{{ user.salary }}</th> <th>{{ user.address }}</th> </tr> {% endfor %} </tbody> </table> <nav aria-label="..." class="text-center"> <ul class="pagination pagination-lg"> <li><a href="/?page={% if single_user_list.has_previous %} {{ single_user_list.previous_page_number }} {% else %} {{ single_user_list.number }} {% endif %} ">上一页</a></li> {% for page in paginator.page_range_new %} {% if page == '...' %} <li><span>...</span></li> {% elif page == paginator.current_page %} <li class="active"><a href="/?page={{ page }}">{{ page }}</a></li> {% else %} <li><a href="/?page={{ page }}">{{ page }}</a></li> {% endif %} {% endfor %} <li><a href="/?page={% if single_user_list.has_next %} {{ single_user_list.next_page_number }} {% else %} {{ single_user_list.number }} {% endif %} ">下一页</a></li> </ul> </nav> <span>共{{ user_list.count }}篇博文。 当前第{{ paginator.current_page }}页, 共{{ paginator.num_pages }}页</span> </div>

最终的实现效果

三、forms组件介绍

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

四、forms校验字段功能

1.在app01下创建一个py文件

2.导入组件

from django import forms

3.定义组件功能

class CheckUser(forms.Form): name = forms.CharField(required=True, # 是否需要该字段默认为True max_length=32, # 最大长度 min_length=4, # 最小长度 label='用户名') # 此字段的详细名称,用于在表单中显示此#字段。 # 默认情况下,如果Field是#Form的一部分,则Django将使用表单域名称的“漂亮”版本。 password = forms.CharField(required=True, max_length=18, min_length=6, label='密码') age = forms.IntegerField(max_value=100, min_value=0, label='年龄')

4.在视图函数中调用

from app01 import myfrom def Up_In(request): if request.method == 'POST': data = request.POST print(data) form = myfrom.CheckUser(data=data) # 传入参数 if form.is_valid(): # 表单匹配正确 可以使用 print('校验通过') else: print(form.cleaned_data) # 校验通过的字段 print('校验失败') # 哪个字段失败了?失败的原因是什么 print(form.errors) print(type(form.errors)) #### 重写了__str__ print(form.errors.as_json()) print(form.errors.as_data()) return render(request, 'Up_In.html')

五、forms渲染模板功能

视图

def automatic_form(request): form = myfrom.CheckUser() return render(request, 'demo.html', {'form': form})

模板

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>半自动渲染模板1</h1> <form action="" method="post"> <p>用户名:{{ form.name }}</p> <p>邮箱:{{ form.password }}</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.password.label }}{{ form.password }}</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_p }} <p><input type="submit" value="提交"></p> </form> </body> </html>
最新回复(0)