今日内容概要
- 批量操作数据
- 自定义分页器(重在思路)
- form组件
- modelform组件
- cookie与session简介
今日内容详细
批量操作数据
浏览器访问一个django路由 立刻创建10万条数据并展示到前端页面
create()、all()
涉及到大批量数据的创建 直接使用create可能会造成数据库崩溃
批量数据创建>>>:bulk_create()
批量数据修改>>>:bulk_update()
def index(request):
# for i in range(100000):
# models.Book.objects.create(title=f'第{i}本书')
book_list = []
for i in range(100000):
book_obj = models.Book(title=f'第{i}本书')
book_list.append(book_obj)
'''上述四行可以简写为一行>>>:列表生成式(列表表达式)'''
models.Book.objects.bulk_create(book_list) # 批量创建数据
book_query = models.Book.objects.all()
return render(request,'bookList.html',locals())
批量数据展示
当数据量比较大的时候 页面展示应该考虑分页
1.QuerySet切片操作
2.分页样式添加
3.页码展示
如何根据总数据和每页展示的数据得出总页码
divmod()
4.如何渲染出所有的页码标签
前端模板语法不支持range 但是后端支持 我们可以在后端创建好html标签然后传递给html页面使用
5.如何限制住展示的页面标签个数
页码推荐使用奇数位(对称美) 利用当前页前后固定位数来限制
6.首尾页码展示范围问题
"""
上述是分页器组件的推导流程 我们无需真正编写
django自带一个分页器组件 但是不太好用 我们自己也写了一个
"""
自定义分页器
from app01.plugins import mypage
book_query = models.Book.objects.all()
page_obj = mypage.Pagination(current_page=request.GET.get('page'),
all_count=book_query.count()
)
page_query = book_query[page_obj.start:page_obj.end]
return render(request, 'bookList.html', locals())
{% for book_obj in page_query %}
<p class="text-center">{{ book_obj.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}
前戏:编写用户登录功能并且校验数据返回提示信息(form表单)
def ab_form(request):
data_dict = {'username':'','password':''}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason':
data_dict['username'] = 'jason是你能随便用的吗'
if password == '123':
data_dict['password'] = '密码就设123???'
return render(request,'ab_form.html',locals())
form组件
1.数据校验
支持提前设置各种校验规则 之后自动校验
2.渲染页面
支持直接渲染获取用户数据的各种标签
3.展示信息
支持针对不同的校验失败展示不同的提示
form类型创建
from django import forms
class MyForm(forms.Form):
name = forms.CharField(max_length=8, min_length=3) # 用户名最长八个字符 最短三个字符
age = forms.IntegerField(max_value=150, min_value=0) # 年龄最小0岁 最大150岁
email = forms.EmailField() # 邮箱必须符合邮箱格式(至少有个@符号)
1.数据校验功能
1.1.传递待校验的数据
form_obj = views.MyForm({'name':'jason','age':18,'email':123})
1.2.判断所有的数据是否符合校验
form_obj.is_valid()
1.3.获取符合校验规则的数据
form_obj.cleaned_data
{'name': 'jason', 'age': 18}
1.4.查阅不符合校验规则的数据及错误原因
form_obj.errors
{'email': ['Enter a valid email address.']}
"""
1.form类中编写的字段默认都是必填的 少传则肯定通不过校验 is_valid
2.校验如果多传了一些字段 则不参与校验 全程忽略
"""
2.渲染标签功能
2.1.方式1(封装程度高 扩展性差)
{{ form_obj.as_p }}
{{ form_obj.as_table }}
{{ form_obj.as_ul }}
2.2.方式2(封装程度低 扩展性好 编写困难)
{{ form_obj.name.lable }}
{{ form_obj.name }}
2.3.方式3(推荐使用)
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}
"""
类中以外的所有标签都不会自动渲染 需要自己编写
"""
3.展示提示信息
form表单如何取消浏览器自动添加的数据校验功能
<form action="" method="post" novalidate>
{% for form in form_obj %}
<p>
{{ form.label }}{{ form }}
<span style="color: red;">{{ form.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit" value="提交">
def func(request):
form_obj = MyForm()
if request.method == 'POST':
form_obj = MyForm(request.POST)
if form_obj.is_valid():
print(form_obj.cleaned_data)
return render(request,'func.html',locals())
重要的字段参数
max_length、min_length
max_value、min_value
label 字段注释
error_messages 错误提示
required 是否为空
widget 标签类型、标签属性
initial 默认值
validators 正则校验
钩子函数
提供自定义的校验方式
局部钩子:校验单个字段
def clean_name(self):
name = self.cleaned_data.get('name')
res = models.User.objects.filter(name=name).first()
if res:
return self.add_error('name','用户名已存在')
return name
全局钩子:校验多个字段
def clean(self):
pwd = self.cleaned_data.get('pwd')
confirm_pwd = self.cleaned_data.get('confirm_pwd')
if not pwd == confirm_pwd:
return self.add_error('confirm_pwd','两次密码不一致')
return self.cleaned_data
form组件源码分析
modelform是form的优化版本 使用更简单 功能更强大
class MyModelForm(forms.ModelForm):
class Meta:
model = models.User
fields = '__all__'
def clean_name(self):
name = self.cleaned_data.get('name')
res = models.User.objects.filter(name=name).first()
if res:
self.add_error('name','用户名已存在')
return name