目录
sweetalert前端插件
django自带的序列化组件
简易分页器
带有页码的分页器
优化后的版本
模块代码
后端代码
Forms组件
校验数据
渲染标签
展示信息
widgets
注意:
sweetalert前端插件
https://github.com/lipis/bootstrap-sweetalert
django自带的序列化组件
以后我们用的序列化组件是DRF
关键模块
from django.core import serializers
作用>>>>把数据序列化成我们需要的格式
使用
from django.core import serializers
def data_json(request):
data = models.Book.objects.all()
data_json = serializers.serialize('json',data) #把QuerySet序列化成JSON格式
return HttpResponse(data_json)
批量数据处理
'''
主要用来优化大批次数据的数据库操作,提高效率
'''
def data_batch(request):
# 1.定义空列表
data_list = []
# 2.把数据添加到列表中
for i in range(1,10000):
# 获取数据对象
book_obj = models.Book(title=f'第{i}本书',price=100,stock=1000,sales=1000)
# 数据对象添加到列表
data_list.append(book_obj)
# 3.执行批量操作
models.Book.objects.bulk_create(data_list)
return HttpResponse('ok')
分页器推导流程
"""
当数据量非常大时,我们一个页面展示不完,所以就创造了分页器
django本身也自带了一个分页器 只是不好用 所以我们自己写!!!
"""
简易分页器
def my_pager(request):
# 获取页码
current_page = request.GET.get('page')
if not request.GET.get('page'):
current_page = 1
# 准备数据参数(以每页十条数据为准)
start_num = (int(current_page)-1)*10
end_num = start_num+10
# 获取切片数据
data_slice = models.Book.objects.all()[start_num:end_num]
return render(request,'data_list.html',locals())
'''
通过控制url的pege参数就可以实现分页
'''
带有页码的分页器
def page(request):
# 准备分页数据
try:
current_page = int(request.GET.get('page'))
except Exception:
current_page = 1
# 准备数据参数(以每页十条数据为准)
start_num = (current_page - 1) * 10
end_num = start_num + 10
# 获取切片数据
data_slice = models.Book.objects.all()[start_num:end_num]
# 获取数据总条数
data_num = models.Book.objects.all().count()
# 获取应该要多少页(以十条每页为标准)
page_num,more = divmod(data_num,10)
if more:
page_num+=1 # 如果有余数,就要多来一页
# 生成标签
html = ''
for i in range(1,page_num+1):
html +='<li><a href="?page=%s">%s</a></li>'%(i,i)
return render(request,'data_list.html',locals())
优化后的版本
def pager(request):
# 准备分页数据
try:
current_page = int(request.GET.get('page'))
except Exception:
current_page = 1
# 准备数据参数(以每页十条数据为准)
start_num = (current_page - 1) * 10
end_num = start_num + 10
# 获取切片数据
data_slice = models.Book.objects.all()[start_num:end_num]
# 获取数据总条数
data_num = models.Book.objects.all().count()
# 获取应该要多少页(以十条每页为标准)
page_num,more = divmod(data_num,10)
if more:
page_num+=1 # 如果有余数,就要多来一页
# 生成标签
html = ''
start_page_num = current_page-5 # 起始显示页码
end_page_num = current_page+6 # 终止显示页码
if start_page_num<1:
start_page_num = 1
if end_page_num >page_num:
end_page_num = page_num
for i in range(start_page_num,end_page_num):
if current_page == i:
html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
continue
html +='<li><a href="?page=%s">%s</a></li>'%(i,i)
return render(request,'data_list.html',locals())
模块代码
class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)
'''
创建utils文件夹
在utils中创建一个py文件并将代码复制进去
需要使用的地方导模块
'''
后端代码
def pager_model(request):
# 获取数据对象
data_queryset = models.Book.objects.all()
# 创建分页器对象
from utils import mypage
pager_obj = mypage.Pagination(current_page=request.GET.get('page'),all_count=data_queryset.count(),per_page_num=10)
# 产生分页对象
page_queryset = data_queryset[pager_obj.start:pager_obj.end]
return render(request,'pager.html',locals())
作用>>>>可以一次性帮我们实现数据校验,标签渲染,信息展示三步操作
使用
# 创建Forms类
from django import forms
class Froms(forms.Form):
username = forms.CharField(max_length=32) # 最大长度32
ags = forms.IntegerField(min_value=0,max_value=100) # 最大为100,最小为0
email = forms.EmailField() # 必须是邮箱格式
校验数据
#1.实例化Forms对象
from app01 import views
form_obj =MyForm({'username':'petter','age':18,'email':'123456'})
#2.执行校验方法
form_obj.is_valid()
TRUE:结果全部合法
FALSE:结果中有不合法的
#3.查看不合法数据及其原因
form_obj.errors
{'email': ['Enter a valid email address.']}
#4.查看符合条件的数据
form_obj.cleaned_data
{'username': 'petter', 'age': 18}
"""
1.forms类中所有的字段数据默认都是必填的 不能少
如果想忽略某些字段 可以添加 required=False
2.forms类中额外传入的字段数据不会做任何的校验 直接忽略
"""
渲染标签
渲染方式1:封装程度高 扩展性较差 主要用于快速生成页面测试功能
{{ form_obj.as_p }} # 竖向
{{ form_obj.as_table }} # 横向
{{ form_obj.as_ul }} # 竖向加点
渲染方式2:封装程度低 扩展性较好 但是字段比较多的情况下不方便
{{ form_obj.username.label }} # 文本提示
{{ form_obj.username }} # 获取用户数据的标签
渲染方式3:推荐使用!!!
{% for form in form_obj %}
<p>
{{ form.label }}
{{ form }}
</p>
{% endfor %}
"""
forms组件只负责渲染获取用户数据的标签
form表单标签和提交按钮需要自己写
渲染标签中文提示 可以使用参数 label指定 不指定默认使用字段名首字母大写
"""
展示信息
forms类中填写的校验性参数前端浏览器会识别并添加校验操作
但是前端的校验是可有可无的 不能指望它!!! 后端必须要有
form表单可以取消浏览器自动添加校验功能的操作
<form action="" method="post" novalidate></form>
"""
{{ form.errors.0 }}
提示信息可以自定义
username = forms.CharField(min_length=3,max_length=8,label='用户名',
error_messages={
'min_length':'用户名最短3位',
'max_length':'用户名最长8位',
'required':'用户名必填'
})
是用来引入bootstrap样式的。
register.html
<div class="container">
<h1 class="text-center">注册功能</h1>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<form action="" method="post" novalidate>
{% for foo in form_obj %}
<p>
<label for="">{{ foo.label }}</label>
{{ foo }}<span style="color: red">{{ foo.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit" value="提交" class="btn btn-success">
</form>
</div>
</div>
</div>
views.py
from django import forms # 引入forms组件
from django.forms import widgets
class UserForm(forms.Form): # 必须继承forms.Form
# forms.CharField和forms.EmailField会渲染为input标签
name = forms.CharField(min_length=3, max_length=8, label='用户名',
error_messages={'required': '用户名不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
pwd = forms.CharField(min_length=3, max_length=8, label='密码',
widget=widgets.PasswordInput(attrs={'class': 'form-control'}) # 密文文本输入框
)
re_pwd = forms.CharField(min_length=3, max_length=8, label='确认密码',
widget=widgets.PasswordInput(attrs={'class': 'form-control'})
)
email = forms.EmailField(label='邮箱', error_messages={'required': '邮箱地址不能为空', 'invalid': '格式错误'},
widget=widgets.EmailInput(attrs={'class': 'form-control'})
)
phone = forms.CharField(min_length=11, max_length=11, error_messages={'required': '手机号不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'}) )
注意:
- 在字段构造中设置error_messages参数修改字段错误信息提示:其中required表示字段不能为空的提示,invalid表示字段格式错误的提示信息。
- 在字段构造函数中配置input类型:设置为文本域、密码域、单选框、复选框等等类型。